为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Vaadin Flow 中将自定义组合框过滤与 DataProvider 结合使用?

如何在 Vaadin Flow 中将自定义组合框过滤与 DataProvider 结合使用?

慕哥9229398 2023-07-28 15:42:14
我们当前使用的是 Vaadin Flow 版本 12.0.7(由于某些原因我们无法升级),并且我们希望覆盖 ComboBox 组件的过滤机制。我的意思是,当用户在组合框内输入输入时,我们希望更改组合框后面的项目的搜索方式。我正在查看Vaadin 文档,了解如何实现组合框的自定义过滤。更具体地说,该部分Filtering by a string看起来很有希望。根据 Vaadin 文档,我们实现了一个自定义接口来适应 ComboBox 的搜索方法:public interface CustomerDataFilter {    List<Customer> fetch(int offset, int limit, String filterText);    int getCount(String filterText);}这非常简单,并且与文档示例几乎 1:1 匹配。然后,我们根据文档创建了一个方法,用数据填充 ComboBox。文档中也几乎使用了 1:1:private DataProvider<Customer, String>createDepartmentDataProvider(CustomerDataFilter service){   return DataProvider.fromFilteringCallbacks(query -> {       // getFilter returns Optional<String>       String filter = query.getFilter().orElse(null);       return service.fetch(query.getOffset(),               query.getLimit(), filter).stream();   }, query -> {       String filter = query.getFilter().orElse(null);       return service.getCount(filter);   });}我们在初始化 ComboBox 的数据时调用上述方法。此时我们还实现了接口(尽管这可能很难看)。然而我们不太确定如何使用这两个接口方法。我们的第一个目标是始终返回所有项目并忽略任何特定过滤,这就是我们sorted始终返回整个列表的原因。这只是为了测试目的,尝试我们是否更改了过滤。public void updateCustomerList() {    List<Customer> sorted = CustomerService.getInstance().findAll();    //for initial sorting    sorted.sort(new CustomerComperator());    DataProvider<Customer, String> test = createDepartmentDataProvider(new CustomerDataFilter() {        @Override        public int getCount(String filterText) {            return 0;        }        @Override        public List<Customer> fetch(int offset, int limit, String filterText) {            return sorted;        }    });    customerCompany.setItems(sorted);    customerCompany.setDataProvider(test);}我们尝试将该getCount值增加到1,但一旦我们将其设置为高于0以下异常,就会发生:The number of items returned by the data provider exceeds the limit specified by the query (1).我们的猜测是,我们必须以某种方式调整getCount和fetch方法,以便它们实现我们的自定义搜索。这不会有问题,因为我们有 ComboBox 和filterText. 我们怎么有点困惑为什么我们getCount还需要一个方法以及如何绕过显示的异常?我们的想法是让getCountalways 返回like10并fetch返回我们列表中sorted关于filterText.任何人都可以详细说明/帮助我们如何实现组合框的自定义过滤或为我们指出正确的轨道吗?
查看完整描述

1 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

您走在正确的轨道上,但您需要首先了解概念DataProvider

在客户端(浏览器),一旦用户与其进行交互,Vaadin 就会请求将数据显示在组合框中。请求的数据类似于“数据中有多少项?” 这是计数查询。假设您有 100 件商品。现在,下一个请求是“给我要显示的前 40 个项目”,这是获取查询。组合框将显示返回的项目。一旦用户向下滚动列表,就会发出另一个数据请求“给我接下来要显示的 40 个项目”等。

总而言之,DataProvider首先要求返回所有项目的计数,然后根据需要逐页获取数据。当用户输入过滤器时这也适用。不同之处在于您的计数和获取查询应考虑过滤器。

示例:用户输入了过滤器“xyz”,现在只有 50 个项目与此过滤器匹配(通过名称或其他内容),因此您将在 count 方法中返回 50,并且您的 fetch 方法应该相应地进行过滤。

您遇到的异常只是指出您的 fetch 方法返回的项目多于 Vaadin 请求的项目(查询参数中的“limit”参数)。这是因为您当前不处理偏移/限制。

您有两种选择来实施您的数据提供程序:

使用列表数据提供者

Vaadin 提供了for 列表ListDataProvider的实现DataProvider。分页已经在实现中完成了,你不必关心它。使用该filteringBy方法根据输入的过滤文本过滤数据。

这种方式更容易,但不可扩展。这意味着如果您有很多项目,您将消耗大量内存和 CPU,因为整个数据都是从后端检索到列表中的。如果您预计商品数量较少,请采用此方法。

或者实现您自己的 DataProvider

您可以实现自己的DataProvider. 我建议从扩展AbstractBackendDataProvider类(javadoc)开始。方法sizeInBackendfetchFromBackend需要实施。请注意在 fetch 方法中实现分页的偏移/限制参数。

如果您将分页委托给数据库(例如 SQL 或 no-sql 数据库),则此方法是可扩展的。内存占用会很低,因为您只在内存中保留一页。


查看完整回答
反对 回复 2023-07-28
  • 1 回答
  • 0 关注
  • 100 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信