如何在 Vaadin 8 Grid 中重新应用过滤器

How to re-apply filters in Vaadin 8 Grid

我已将过滤器添加到我的网格中,如下所示:

filterTextField.addValueChangeListener(event -> {
        myListDataProvider.addFilter(
                columnName, 
                value-> value.toLowerCase().contain(filterTextField.getValue()));
    });

这将设置并应用过滤器。但是后来我在网格上执行了一个操作,需要重新加载这些项目:

grid.setItems(reloadItemsDueToAction());

当我这样做时,filterTextField 当然仍然填充并且网格被重新加载,但是问题是我不知道如何重新应用在 ListDataProvider 使网格再次根据 filterTextField 进行过滤。过滤器仍应在 ListDataProvider 中设置,但如何在网格中应用它们?

在我看来,目前(8.1.5)只能通过重新设置 DataProvider 和过滤器来实现,例如:

private ListDataProvider<Entity> ldp
   = new ListDataProvider<>(getGridItems()); // initial grid data

// then somewhere update grid & re-apply filters

SerializablePredicate<Entity> filter = ldp.getFilter(); // store filter
ldp = new ListDataProvider<>( getGridItems() ); // new ldp with fresh data
grid.setDataProvider(ldp); // instead of setItems()
if(filter!=null) ldp.addFilter(filter); // re-apply stored filter

同样的方式也适用于 Table/Container

如果您使用 setItems(),我猜 Grid 不再使用之前的 DataProvider 并且将过滤器设置为之前的 DataProvider 将不会传播到 Grid .我不知道这是否明智,但如果你真的需要使用 setItems() 那么也许是这样的:

ListDataProvider<Entity> ldp = ((ListDataProvider<Entity>)g.getDataProvider());
SerializablePredicate<Entity> filter = ldp.getFilter();
grid.setItems(getGridItems());
ldp = ((ListDataProvider<Entity>)g.getDataProvider());
if(filter!=null) ldp.addFilter(filter);

均使用多个过滤器进行了测试。

在网格上创建 TextField 作为过滤器,保留地图中的值,覆盖 hasValue,在获取数据到网格后添加