gpt4 book ai didi

java - 如何在 Vaadin Flow 中使用带有 DataProvider 的自定义组合框过滤?

转载 作者:行者123 更新时间:2023-12-05 02:11:05 26 4
gpt4 key购买 nike

我们目前使用的是 Vaadin Flow 版本 12.0.7(由于某些原因我们无法升级)并且我们想要覆盖 ComboBox 组件的过滤机制。我的意思是,当用户在 ComboBox 中输入内容时,我们想更改搜索 ComboBox 后面的项目的方式。

我在看这个Vaadin documentation关于如何实现组合框的自定义过滤。更具体地说,Filtering by a string 部分看起来很有前途。

根据 Vaadin 文档,我们实现了一个自定义接口(interface),用于调整 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 初始化数据时调用上述方法。在这一点上,我们还实现了接口(interface)(尽管这可能很难看)。然而,我们不太确定如何使用这两种接口(interface)方法。我们的第一个目标是始终返回所有项目并忽略任何特定的过滤,这就是我们始终返回整个 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,就会发生以下异常:

数据提供者返回的项目数超过了查询指定的限制 (1)。

我们的猜测是,我们必须以某种方式调整 getCountfetch 方法,使其实现我们的自定义搜索。这不会有问题,因为我们有 ComboBox 和 filterText 背后的数据。为什么我们还需要一个 getCount 方法以及我们如何绕过显示的异常?我们的想法是让 getCount 总是像 10 一样返回,并且在 fetch 中返回我们的 sorted 列表的子集过滤文本

谁能详细说明/帮助我们如何为 ComboBox 实现自定义过滤或为我们指明正确的轨道?


感谢 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()));
}

CustomerProvider 仅实现适用的 DataProvider 接口(interface)。之后,我们可以简单地应用 filteringByPrefix 方法来更改过滤行为。

最佳答案

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

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

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

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

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

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

使用 ListDataProvider

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

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

或者实现你自己的DataProvider

您可以实现自己的 DataProvider。我建议首先扩展 AbstractBackendDataProvider 类 ( javadoc )。需要实现方法 sizeInBackendfetchFromBackend。请注意 offset/limit 参数以在 fetch 方法中实现分页。

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

关于java - 如何在 Vaadin Flow 中使用带有 DataProvider 的自定义组合框过滤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57921932/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com