【问题标题】:Primefaces Paginate Lazy DataTable without count rowPrimefaces Paginate Lazy DataTable 没有计数行
【发布时间】:2016-05-12 13:05:27
【问题描述】:

在我的页面中:

                    <p:dataTable id="myTable" lazy="true" widgetVar="myTable" value=".." paginator="true" paginatorPosition="bottom" rows="10" ...>
                    <p:ajax event="page" oncomplete="myTable" />
                    ...
                    </p:dataTable>

在我的 bean 中:

                    ...
                    private LazyDataModel list;
                    ...                     
                    public void search() {
                        list = new LazyDataModel<SomeDTO>() {
                            private static final long serialVersionUID = 1L;
                            List<SomeDTO> result = null;

                            @Override
                            public List<SomeDTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {                                    
                                List<SomeDTO> result = service.search(searchedName, first, pageSize);
                                // SOME CODE HERE FOR PAGINATION ?? BUT WHAT
                                return result;
                            }

                        };
                        // HOW TO DELETE THIS EXTRA REQUEST
                        list.setRowCount(service.search(searchedName));
                    }

我的问题是如何从结果 (size+1) 中设置行计数。我不想从 DB 中获取计数,因为我确信我们可以在不请求 DB 的情况下计算 rowCount。

【问题讨论】:

    标签: primefaces datatable rowcount pagination lazydatamodel


    【解决方案1】:

    PrimeFaces 不支持此功能。 A fix has been checked in to trunk on Feb 11th 2016, tagged 6.0(所以它至少应该在当前的 6.0RCx 版本中)。我不确定它是否在 Elite 版本中 >=5.2.20 或 >=5.3.7(从 2 月 12 日开始)

    这不起作用的一个重要原因是您可能在服务器端的加载方法中执行的更新行计数没有应用于分页器客户端。但是,由于它从服务器传输到客户端,您可以在每个 ajax 调用的 oncomplete 中更新它。其实这是patch的很大一部分(另一部分是从ajax响应中读取值)。

    在例如组合中调用它ajax 页面事件的 oncomplete 将解决问题:

    function updatePaginator(xhr, status, args) {
        var paginator = PF('DataTableWidgetVar').paginator;
        paginator.cfg.rowCount=args.totalRecords;
        paginator.cfg.pageCount = Math.ceil(value / paginator.cfg/rows)||1;
        paginator.updateUI();
    }
    

    然后你可以在每次调用load方法中, - 尝试读取pagesize+1条记录 - 如果您可以读取 pageSize+1(但仍返回 pageSize 记录),请将计数设置为此 - 如果它们是 pageSize 或更少,则将计数设置为读取的行数。

    【讨论】:

    • 如果您查看我的解决方案,我有: 这个命令在 ajax 页面后刷新数据表。我已经对其进行了测试,并且效果很好。如果你不确定你的答案不要发布。
    • 有两个请求,一个用于 p:ajax 页面事件,另一个用于 p:remoteCommand。但这不是问题。我的问题是避免请求数据库获取计数行而不是数据表。
    • 这是 p:remoteCommand 的另一个问题,数据表的加载执行了两次。你知道如何在没有 p:remoteCommand 的情况下刷新数据表吗?我试过 update="datatable" 但不起作用?
    【解决方案2】:

    Primefaces 分页 Lazy DataTable 需要两个查询,一个查询返回一个页面作为限制的结果,另一个查询知道数据的总大小。

    【讨论】:

    • 这两个查询不是必须的,我们可以根据我们的服务返回列表的大小+1来动态计算页数,这种方案的好处是我们不必复制服务从 db 中获取计数的方法,尤其是对于非常复杂的搜索查询。
    【解决方案3】:

    好的,我明白了。 首先在你的页面中你需要这个:

                        <p:remoteCommand name="updateMyTable" update="#{p:component('myTable')}" process="@this" />
                        <p:dataTable id="myTable" lazy="true" widgetVar="myTable" value=".." paginator="true" paginatorPosition="bottom" rows="10" ...>
                        <p:ajax event="page" oncomplete="updateMyTable()" />
                        ...
                        </p:dataTable>
    

    在您的 bean 中更改加载方法,如下所示:

                                @Override
                                public List<SomeDTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {                                    
                                    List<SomeDTO> result = service.search(searchedName, first, pageSize);
                                    if (first <= pageSize) {
                                        this.setRowCount(this.getRowCount() + result.size() + 1);
                                    } else if (result != null && result.size() > 0 && (result.size() >= pageSize)) {
                                        this.setRowCount(this.getRowCount() + result.size());
                                    }
                                    return result;
                                }
    

    【讨论】:

    • 这会更新数据表。两次。查询被执行两次......我认为这不是你想要的。
    • 不,何先生什么都知道,请在判断人员之前读出问题和提供的解决方案。显然您不知道 primefaces 数据表延迟加载及其工作原理!
    • 首先,我不是在评判人,而是在评判答案。虽然它在技术上可能有效,但它不是一个有效的解决方案,也不需要。你说阅读答案很了不起。 我是创建我的回答中提到的“已接受”PrimeFaces 补丁的人,您注意到了吗?我在论坛和旧问题列表中为 PrimeFaces 数据表提出了多项其他改进建议,包括关于重复嵌套的数据表。我有那些在我的环境中工作了很长时间,所以我知道延迟加载**。因此,在判断人之前请弄清记录
    • 这里数据表更新两次不是remoteCommand的问题。 1 更新是由基本分页引起的,第二个是由于调用了一个远程命令,该命令会根据您的状态更新数据表。所以它可以(由您)实现。如果您想要完整更新数据表以便还可以更新页眉/页脚,那么 StackOverflow 中有几个与此相关的问题,但这是一个不同的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 2015-01-27
    • 2013-10-03
    • 2016-10-02
    • 1970-01-01
    相关资源
    最近更新 更多