Vaadin Grid 重新计算 Column Widths 问题——如何让它更一致
Vaadin Grid recalculateColumnWidths problems - how to make it more consistant
在我的 Vaadin 7 应用程序中,我在加载大多数网格后调用 grid.recalculateColumnWidths();
。我这样做是因为当我刷新一个特定的 Grid
时,我注意到列宽没有改变。这修复了这个特定的 Grid
,可能还有其他一些,但不是所有的网格。 documentation 并没有真正解释一些事情,我希望有人能澄清一些事情,这样我就可以解决问题:
- 什么时候触发?换句话说,在它不起作用的情况下,它会不会是时间问题?对于 Vaadin Flow,我看到有人建议做类似
grid.getElement().executeJs("setTimeout(() => { this.recalculateColumnWidths() }, 0)");
的事情,所以我想这是一个长期存在的问题。此外,如果您查看 low-level API,您会发现它清楚地表明在调用此函数后您不能依赖正确的列宽,因为它不会立即完成。当我在调试器中进入它时,它看起来像是将它添加到操作队列中以稍后完成,因此这似乎可以确认事情。我怎样才能提高触发调整大小的机会?
- 它如何处理我明确设置宽度的列?如果这在某处记录(在 API 文档或某处的某个帖子中),我找不到它。当我进入调试器时,有点难以确定。
- 如果我添加一个按钮来强制调整大小,调用这个
recalculateColumnWidths()
方法,类似于一些用户在 Vaadin 14 here 中所做的,它会起作用吗?所以假设我们将宽度初始化为一个值(所以我们故意截断一些列,迫使它们使列变大),并且我们希望在他们单击此按钮时完全显示所有列中的所有内容,有没有办法做那?也许清除所有明确的列大小并让正常的调整大小逻辑起作用?
让我先说明一下列宽(重新)计算是一项复杂且相对昂贵的任务。它需要在正确的时间完成——不能太早也不能太晚。如果做得太早,随后对布局的更改将意味着需要重新计算尺寸。如果完成得太晚,则意味着 UI 将需要更长的时间才能再次响应。尝试通过比需要更频繁地重新计算列宽来“安全行事”是性能下降的一个简单来源 - 网格可以有很多列,因此重新计算的成本很容易复合。
- 触发列宽重新计算的情况较多。一些基本情况是在 UI 的布局阶段,或者当网格重新附加时,或者当网格的内部宽度发生变化时(例如由于浏览器 window 调整大小),或者当某些事情发生时完成列大小(例如设置最小或最大宽度或扩展比率)。正如您在此处看到的那样,调整大小确实已排队:https://github.com/vaadin/framework/blob/7.7/client/src/main/java/com/vaadin/client/widgets/Grid.java#L3280。绝对有可能存在时间问题。如果没有计算出错的确切条件,很难说什么时候是重试的好地方 - 没有地方可以“真正最终渲染所有内容,以便您可以安排更多渲染”。
- 固定宽度列的大小不需要计算,因此从这个角度来看这些列应该可以忽略。事实上,如果您可以为所有或大多数列设置固定宽度,这很可能意味着显着的性能提升。
- 是的,它可以工作。
在我的 Vaadin 7 应用程序中,我在加载大多数网格后调用 grid.recalculateColumnWidths();
。我这样做是因为当我刷新一个特定的 Grid
时,我注意到列宽没有改变。这修复了这个特定的 Grid
,可能还有其他一些,但不是所有的网格。 documentation 并没有真正解释一些事情,我希望有人能澄清一些事情,这样我就可以解决问题:
- 什么时候触发?换句话说,在它不起作用的情况下,它会不会是时间问题?对于 Vaadin Flow,我看到有人建议做类似
grid.getElement().executeJs("setTimeout(() => { this.recalculateColumnWidths() }, 0)");
的事情,所以我想这是一个长期存在的问题。此外,如果您查看 low-level API,您会发现它清楚地表明在调用此函数后您不能依赖正确的列宽,因为它不会立即完成。当我在调试器中进入它时,它看起来像是将它添加到操作队列中以稍后完成,因此这似乎可以确认事情。我怎样才能提高触发调整大小的机会? - 它如何处理我明确设置宽度的列?如果这在某处记录(在 API 文档或某处的某个帖子中),我找不到它。当我进入调试器时,有点难以确定。
- 如果我添加一个按钮来强制调整大小,调用这个
recalculateColumnWidths()
方法,类似于一些用户在 Vaadin 14 here 中所做的,它会起作用吗?所以假设我们将宽度初始化为一个值(所以我们故意截断一些列,迫使它们使列变大),并且我们希望在他们单击此按钮时完全显示所有列中的所有内容,有没有办法做那?也许清除所有明确的列大小并让正常的调整大小逻辑起作用?
让我先说明一下列宽(重新)计算是一项复杂且相对昂贵的任务。它需要在正确的时间完成——不能太早也不能太晚。如果做得太早,随后对布局的更改将意味着需要重新计算尺寸。如果完成得太晚,则意味着 UI 将需要更长的时间才能再次响应。尝试通过比需要更频繁地重新计算列宽来“安全行事”是性能下降的一个简单来源 - 网格可以有很多列,因此重新计算的成本很容易复合。
- 触发列宽重新计算的情况较多。一些基本情况是在 UI 的布局阶段,或者当网格重新附加时,或者当网格的内部宽度发生变化时(例如由于浏览器 window 调整大小),或者当某些事情发生时完成列大小(例如设置最小或最大宽度或扩展比率)。正如您在此处看到的那样,调整大小确实已排队:https://github.com/vaadin/framework/blob/7.7/client/src/main/java/com/vaadin/client/widgets/Grid.java#L3280。绝对有可能存在时间问题。如果没有计算出错的确切条件,很难说什么时候是重试的好地方 - 没有地方可以“真正最终渲染所有内容,以便您可以安排更多渲染”。
- 固定宽度列的大小不需要计算,因此从这个角度来看这些列应该可以忽略。事实上,如果您可以为所有或大多数列设置固定宽度,这很可能意味着显着的性能提升。
- 是的,它可以工作。