如何设置 DataProvider 从后端获取的元素数量?

How to set the amount of elements that will be fetched from backend by a DataProvider?

我想将一些数据从网格延迟加载到我的 Vaadin 视图中。网格行有时非常大,所以我想限制一次加载的行数,假设为 2。

我尝试使用 DataProvider.fromCallbacks() 来做到这一点。不幸的是,我没有得到我想要的结果,而且我对传递给该方法的两个函数有点困惑。

据我正确理解,传递的第一个函数描述了如何获取项目,第二个函数告诉 DataProvider 可以获取的最大可能项目数量。

fromCallbacks(CallbackDataProvider.FetchCallback fetchCallback, CallbackDataProvider.CountCallback countCallback) Creates a new data provider that uses callbacks for fetching and counting items from any backing store.

我尝试了以下方法,但它总是会导致获取很多项目。 (列表中的 17 个项目导致获取 17 个项目,列表中的 120 个项目导致 50 个批次)

    List<SomeObject> data = ... // filled with objects

    DataProvider<CustromCell, Void> lazyLoadingProvider
            = DataProvider.fromCallbacks(
                    query -> {
                        int offset = query.getOffset();
                        int limit = query.getLimit(); // Is this the amount of items that are fetched in one step?

                        if (offset + limit > data.size()) 
                            return data.stream();

                        List<CustromCell> cells = data.subList(offset,offset+limit); 
                                                                 //(offest,offset+2) crashes
                        return cells.stream()
                    },
                    query -> data.size() // Max possible items to fetch
            );
            grid.setDataProvider(lazyLoadingProvider);

具有以下行为:

Size Of Data: 219
Offset: 0
Limit: 50

Size Of Data: 219
Offset: 50
Limit: 50

Size Of Data: 219
Offset: 100
Limit: 50

Size Of Data: 219
Offset: 150
Limit: 50

Size Of Data: 219
Offset: 200
Limit: 19

我必须调用 Query 对象的 getOffset()getLimit(),否则会抛出异常。如果我理解正确,那么限制会告诉我应该获取多少项目(在我的情况下目标是 2)但是对象是不可变的所以我不能更改这个值 (Query API)?

tl;dr 如何告诉 DataProvider 一次只获取网格中的 2 个项目?

编辑:我发现 github 个与我的问题相关的问题 (#6072, #3830)

编辑 2:合并了一个 github 问题,因此 getLimit() 方法的工作原理更加清晰:https://github.com/vaadin/flow/issues/6996

我找到了解决方案。

query.getLimit() 方法取决于组件(即网格)的页面大小。

引用 Grid API:

Grid()

Creates a new instance, with page size of 50.

我的网格是这样初始化的:Grid a = new Grid(); 导致页面大小为 50。在这种情况下,query.getLimit() 将 return 50。

Grid(int pageSize)

Creates a new instance, with the specified page size.

像这样初始化网格:Grid a = new Grid(5);。在这种情况下,query.getLimit() 现在将 return 5,而 DataProvider 将仅获取接下来的 5 个元素。

编辑:关于这个 SO 问题的 github 问题已合并:https://github.com/vaadin/flow/issues/6996

更准确地说,查询限制取决于 2 个主要条件:

  • 网格上的页面大小设置(正如您已经找到的那样)
  • 并且 - 如果您使用的是数据提供者 - 数据提供者大小

以及其他 2 个次要标准/行为:

  • 您可以在 UI 中一次显示多少个元素。如果您的网格一次可以显示超过设置的页面大小,那么查询限制将根据数据提供者大小和我猜的默认页面大小 (50)

    自动调整
  • 因为 网格可能会改变你的查询限制 取决于我刚才解释的内容,如果你刷新你的数据(因为你对数据应用过滤例如提供程序),您的限制将不再是网格页面大小,除非您在刷新数据之前再次专门设置它,例如:

    grid.setPageSize(GRID_PAGE_SIZE);
    grid.getDataProvider().refreshAll();
    

因此,假设您的数据提供者 return 34 个结果,您将页面大小设置为 5,并且在 UI 中显示无限数量的结果,您将有以下行为:

  1. 获取前 5 个(页面大小设置)元素
  2. 发现您可以在 UI 上显示更多元素,因此在数据提供程序上触发第二次提取
  3. 从偏移量 5 获取到限制 34

我发现这个组合根本没有记录..