Vaadin中BackEndDataProvider实现Grid动态过滤的正确方式问询
Vaadin中BackEndDataProvider结合Grid实现动态过滤的正确方式
核心原理
BackEndDataProvider的设计初衷就是支持后端分页、排序和过滤,无需重复绑定DataProvider(即调用grid.setItems())。关键是让Grid感知过滤器的变化,并触发DataProvider重新执行查询。
正确实现步骤
1. 确保DataProvider的查询逻辑正确绑定过滤器
你的AgreementManager(实现BackEndDataProvider)需要在fetch和count方法中,正确使用当前的过滤器参数。推荐使用Vaadin Query自带的过滤器传递机制:
public class AgreementManager implements BackEndDataProvider<Agreement, MyFilter> { private final AgreementRepository repository; @Override public Stream<Agreement> fetch(Query<Agreement, MyFilter> query) { // 从Query中获取当前生效的过滤器 MyFilter filter = query.getFilter().orElse(null); // 结合分页参数调用后端查询 return repository.findFiltered(filter, query.getOffset(), query.getLimit()); } @Override public int count(Query<Agreement, MyFilter> query) { MyFilter filter = query.getFilter().orElse(null); // 返回过滤后的总条数 return repository.countFiltered(filter); } }
2. 视图层触发过滤的正确方式
当过滤器参数变更时,直接调用Grid的setFilter()方法即可,Grid会自动触发DataProvider重新执行fetch和count:
// 初始化时绑定DataProvider BackEndDataProvider<Agreement, MyFilter> dataProvider = new AgreementManager(); Grid<Agreement> grid = new Grid<>(Agreement.class); grid.setDataProvider(dataProvider); // 过滤器变更时触发刷新 MyFilter newFilter = buildFilterFromInput(); // 从过滤行/表单构建新过滤器 grid.setFilter(newFilter); // 无需额外调用refreshAll,Grid自动处理
3. 自定义过滤器维护的备选方案
如果你的业务需要在DataProvider内部维护过滤器状态(而非依赖Query传递),需在更新过滤器后手动触发刷新:
// AgreementManager内部维护过滤器 public class AgreementManager implements BackEndDataProvider<Agreement, Void> { private MyFilter currentFilter; private final AgreementRepository repository; public void setCurrentFilter(MyFilter filter) { this.currentFilter = filter; } @Override public Stream<Agreement> fetch(Query<Agreement, Void> query) { return repository.findFiltered(currentFilter, query.getOffset(), query.getLimit()); } @Override public int count(Query<Agreement, Void> query) { return repository.countFiltered(currentFilter); } } // 视图层操作 agreementManager.setCurrentFilter(newFilter); agreementManager.refreshAll(); // 通知Grid重新查询数据
常见误区规避
- 不要重复调用
grid.setItems(dataProvider):这会重新绑定DataProvider,属于冗余操作,不符合Vaadin设计意图。 - 若
refreshAll无效,检查fetch/count方法是否真的使用了最新的过滤器参数,确保过滤器变更后状态能被正确读取。 - 优先使用不可变过滤器对象:每次过滤条件变更时创建新的过滤器实例,避免因可变对象的内部修改导致状态感知失效。
内容的提问来源于stack exchange,提问作者Curtis Snowden
相关产品推荐
相关产品推荐

