LOL*_*dad 3 java combobox vaadin vaadin-flow
我们当前使用的是 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);
}
Run Code Online (Sandbox Code Playgroud)
这非常简单,并且与文档示例几乎 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);
});
}
Run Code Online (Sandbox Code Playgroud)
我们在初始化 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);
}
Run Code Online (Sandbox Code Playgroud)
我们尝试将该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.
任何人都可以详细说明/帮助我们如何实现组合框的自定义过滤或为我们指出正确的轨道吗?
感谢 Steffen Harbichs 的回答,我们找到了一种实现过滤数据提供程序的方法。基本上这就是所需的一切:
public void updateCustomerList() {
List<Customer> sorted = CustomerService.getInstance().findAll();
sorted.sort(new CustomerComperator());
customerCompany.setItems(sorted);
ListDataProvider<Customer> listTest = new ListDataProvider<>(sorted);
customerCompany.setDataProvider(listTest.filteringByPrefix(new CustomerProvider()));
}
Run Code Online (Sandbox Code Playgroud)
唯一CustomerProvider实现适用的 DataProvider 接口。之后我们可以简单地应用该filteringByPrefix方法来更改过滤行为。
您走在正确的轨道上,但您需要首先了解概念DataProvider。
在客户端(浏览器),一旦用户与其进行交互,Vaadin 就会请求将数据显示在组合框中。请求的数据类似于“数据中有多少项?” 这是计数查询。假设您有 100 件商品。现在,下一个请求是“给我要显示的前 40 个项目”,这是获取查询。组合框将显示返回的项目。一旦用户向下滚动列表,就会发出另一个数据请求“给我接下来要显示的 40 个项目”等。
总而言之,DataProvider首先要求返回所有项目的计数,然后根据需要逐页获取数据。当用户输入过滤器时这也适用。不同之处在于您的计数和获取查询应考虑过滤器。
示例:用户输入了过滤器“xyz”,现在只有 50 个项目与此过滤器匹配(通过名称或其他内容),因此您将在 count 方法中返回 50,并且您的 fetch 方法应该相应地进行过滤。
您遇到的异常只是指出您的 fetch 方法返回的项目多于 Vaadin 请求的项目(查询参数中的“limit”参数)。这是因为您当前不处理偏移/限制。
您有两种选择来实施您的数据提供程序:
Vaadin 提供了for 列表ListDataProvider的实现DataProvider。分页已经在实现中完成了,你不必关心它。使用该filteringBy方法根据输入的过滤文本过滤数据。
这种方式更容易,但不可扩展。这意味着如果您有很多项目,您将消耗大量内存和 CPU,因为整个数据都是从后端检索到列表中的。如果您预计商品数量较少,请采用此方法。
您可以实现自己的DataProvider. 我建议从扩展AbstractBackendDataProvider类(javadoc)开始。方法sizeInBackend和fetchFromBackend需要实施。请注意在 fetch 方法中实现分页的偏移/限制参数。
如果您将分页委托给数据库(例如 SQL 或 no-sql 数据库),则此方法是可扩展的。内存占用会很低,因为您只在内存中保留一页。
| 归档时间: |
|
| 查看次数: |
2558 次 |
| 最近记录: |