Vaadin:过滤器的菊花链?

Vaadin: Daisy chain of filters?

我现在有这个特殊问题 - 我有一个网格,我试图通过多个过滤器过滤数据。为此,我使用文本框作为过滤条件的输入字段。

我的网格有三列(名字、姓氏、地址),我希望能够一个接一个地链接过滤操作。所有值均取自 MySQL 数据库。

基本上过滤过程应该是这样的:

FirstName ^ LastName ^ Address

例如,三列网格:

在 First Name 列的过滤器中,我输入了变量 Aa,这将导致 table 看起来像这样:

但是,如果我决定将 D 输入到姓氏过滤器中,它 returns 结果如下(忽略第一个过滤器的修改):

而不是像这样的预期结果:

我通过网格过滤的方式是这样的:

firstNameFilter.addValueChangeListener( e->
    {
        Notification.show(e.getValue());

        ldp.setFilter(desc -> 
        {
            return StringUtils.containsIgnoreCase(desc.getFName(), firstNameFilter.getValue());
        });
    });     
    firstNameFilter.setValueChangeMode(ValueChangeMode.EAGER);

在考虑以前的过滤操作的同时过滤多列的最佳方法是什么?

listDataProvider.setFilter(...) 将覆盖任何现有过滤器。
我已经编写了 an answer about this very topic,其中包含可供复制粘贴的完整示例代码,以及显示多个过滤器按预期工作的屏幕截图。
它最重要的收获是:

Every time that any filter value changes, I reset the current filter using setFilter. But within that new Filter, I will check the values of ALL filter fields, and not only the value of the field whose value just changed. In other words, I always have only one single filter active, but that filter accounts for all defined filter-values.


这是您的代码的样子:

firstNameFilter.addValueChangeListener( e-> this.onFilterChange());
lastNameFilter.addValueChangeListener( e-> this.onFilterChange());
addressFilter.addValueChangeListener( e-> this.onFilterChange());
// sidenote: all filter fields need ValueChangeMode.EAGER to work this way


private void onFilterChange(){
    ldp.setFilter(desc -> {
        boolean fNameMatch = true;
        boolean lNameMatch = true;
        boolean addressMatch = true;

        if(!firstNameFilter.isEmpty()){
            fNameMatch = StringUtils.containsIgnoreCase(desc.getFName(), firstNameFilter.getValue());
        }
        if(!lastNameFilter.isEmpty()){
            lNameMatch = StringUtils.containsIgnoreCase(desc.getLName(), lastNameFilter.getValue());
        }
        if(!addressFilter.isEmpty()){
            addressMatch = StringUtils.containsIgnoreCase(desc.getAddress(), addressFilter.getValue());
        }

        return fNameMatch && lNameMatch && addressMatch;
    });
});