Java 将过滤器重新应用于Vaadin流14中的ListDataProvider(用于网格小部件)

Java 将过滤器重新应用于Vaadin流14中的ListDataProvider(用于网格小部件),java,gridview,filter,vaadin,vaadin-flow,Java,Gridview,Filter,Vaadin,Vaadin Flow,在14个web应用程序中,我的布局上有一个小部件,由一个 似乎当我打电话时,过滤立即生效。(如果我错了,请纠正我。) 我的过滤器基于小部件的状态。当用户选中或取消选中该小部件时,我希望过滤开始,在网格中出现或多或少的项目 我想我需要向复选框小部件添加一个侦听器。我想那应该是打电话给或。或者可能 ➥ 我的问题是:在该侦听器中,我应该如何使筛选器重新应用于数据提供程序,从而更改网格中显示的项目 我是不是应该先打电话,然后再打电话重置过滤器?似乎应该有更直接的方法 打电话似乎没有效果。在阅读文档时,应

在14个web应用程序中,我的布局上有一个小部件,由一个

似乎当我打电话时,过滤立即生效。(如果我错了,请纠正我。)

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

我想我需要向
复选框
小部件添加一个侦听器。我想那应该是打电话给或。或者可能

➥ 我的问题是:
在该侦听器中,我应该如何使筛选器重新应用于数据提供程序,从而更改网格中显示的项目

我是不是应该先打电话,然后再打电话重置过滤器?似乎应该有更直接的方法

打电话似乎没有效果。在阅读文档时,应调用该方法(a)更改数据提供程序已提供的项目的内容,或(b)重新填充数据提供程序提供的项目组。因此,
refreshAll
似乎与我的目标无关。在我的
Grid
小部件中,
ListDataProvider
内容是固定不变的。我只想通过重新激活过滤器来显示/隐藏该网格中的项目。

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

Boolean value = this.legacy.getValue();  // Captured once, not when user checks/unchecks the checkbox widget.
listDataProvider.setFilterByValue(Product::getLegacy, value);
解决方案 您需要捕获
复选框
小部件在其值更改时的当前状态,当它被选中或取消选中时

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

this.legacy.addValueChangeListener(
    event ->
    listDataProvider
    .setFilterByValue(
        Product::getLegacy , 
        event.getValue()
    )
;
由于所有的
set
方法都在清除任何现有的过滤器,因此不需要在这两者之间执行操作。有单独的
add
方法可以保留现有的过滤器

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

listDataProvider.setFilter(
    product ->
    product.getLegacy().equals( this.legacy.getValue() )
);
通过在上面的那一行中使用lambda,当过滤器通过数据提供程序中的项目执行比较时,
遗留
复选框小部件的当前状态会被动态捕获。

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

Boolean value = this.legacy.getValue();  // Captured once, not when user checks/unchecks the checkbox widget.
listDataProvider.setFilterByValue(Product::getLegacy, value);
解决方案 您需要捕获
复选框
小部件在其值更改时的当前状态,当它被选中或取消选中时

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

this.legacy.addValueChangeListener(
    event ->
    listDataProvider
    .setFilterByValue(
        Product::getLegacy , 
        event.getValue()
    )
;
由于所有的
set
方法都在清除任何现有的过滤器,因此不需要在这两者之间执行操作。有单独的
add
方法可以保留现有的过滤器

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

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

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

根据我的经验,当过滤器更改时,您只需再次设置过滤器(例如,在复选框的值更改侦听器中)。问得好。@SteffenHarbich我的过滤器实际上并没有改变。过滤器内用于比较的值(复选框)正在更改。当使用复选框选中和取消选中该复选框时,我需要再次运行筛选器并重新评估网格中的项目列表。根据我的经验,您只需在筛选器更改时再次设置筛选器(例如,在复选框的值更改侦听器中)。问得好。@SteffenHarbich我的过滤器实际上并没有改变。过滤器内用于比较的值(复选框)正在更改。当use选中并取消选中该复选框时,我需要再次运行过滤器并重新评估网格中的项目列表。