将过滤器重新应用于 Vaadin Flow 14 中的 ListDataProvider(对于 Grid 小部件)

Re-apply filter to ListDataProvider (for a Grid widget) in Vaadin Flow 14

Vaadin Flow 14 web app, I have a Grid widget on my layout, backed by a ListDataProvider

好像我调用ListDataProvider::setFilter的时候,过滤就立即生效了。 (如果我错了请纠正我。)

listDataProvider.setFilterByValue(
        Product :: getLegacy ,      // Boolean property on my pojo `Product`. 
        this.legacy.getValue()      // `this.legacy` is a Vaadin `Checkbox` widget. The `getValue` method returns a `Boolean` (presumably). 
);

我的过滤器基于 Checkbox 小部件的状态。当用户选中或取消选中该小部件时,我希望过滤开始,或多或少的项目出现在 Grid 小部件中。

我想我需要向 Checkbox 小部件添加一个侦听器。我想这应该是对 addValueChangeListener or addClickListener. Or maybe addCheckedChangeListener 的调用?

➥ 我的问题是:
在那个监听器中,我应该怎么做才能使过滤器重新应用于数据提供者,从而改变哪个项目出现在我的网格中?

我应该直接打电话给 clearFilters, followed by resetting the filter with a call to setFilter 吗?似乎应该有更直接的方法。

调用ListDataProvider::refreshAll好像没有效果。在我阅读文档时,应该调用该方法 (a) 当更改数据提供者已提供的项目的 content 时,或 (b) 当 重新填充 数据提供者提供的项目组。所以 refreshAll 似乎与我的目标无关。在我的 Grid 小部件中,ListDataProvider 内容是固定不变的。我只是想通过重新激活过滤器 show/hide 该网格中的项目。

问题

您的代码中的问题是行 this.legacy.getValue() 在您定义此过滤器时捕获了 Checkbox 小部件的值。要比较的值是在设置过滤器时从组件中提取的,即使更新了组件,该值也保持不变。它基本上与将其分成两行相同:

Boolean value = this.legacy.getValue();  // Captured once, not when user checks/unchecks the checkbox widget.
listDataProvider.setFilterByValue(Product::getLegacy, value);

解决方案

Checkbox 小部件的值发生变化时,当它被选中或取消选中时,您需要捕获它的当前状态。

类似这样,侦听器使用小部件的当前值重置新过滤器。

this.legacy.addValueChangeListener(
    event ->
    listDataProvider
    .setFilterByValue(
        Product::getLegacy , 
        event.getValue()
    )
;

您不需要在两者之间执行 clearFilters(),因为所有 set 方法都会清除任何现有过滤器。有单独的 add 方法可以保留现有过滤器。

与您在问题中陈述的相反,refreshAll() 方法确实会导致过滤器再次针对提供程序中的所有项目 运行。 如果过滤器的定义方式是每次调用时都从组件中读取当前值,则可以使用 refreshAll() 使过滤器再次求值。

listDataProvider.setFilter(
    product ->
    product.getLegacy().equals( this.legacy.getValue() )
);

通过在上面那行中使用 lambda,legacy 复选框小部件的当前状态在过滤器通过数据提供程序中的项目执行比较时被即时捕获。