【问题标题】:PrimeFaces dataTable: how to catch rows-per-page event?PrimeFaces dataTable:如何捕获 rows-per-page 事件?
【发布时间】:2014-02-18 08:23:42
【问题描述】:

我创建了一个 PrimeFaces 数据表:

<p:dataTable id="locationTable" value="#{bean.object}" var="item"
  paginator="true"
  rows="10" 
  paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink}{LastPageLink} {RowsPerPageDropdown}" 
  rowsPerPageTemplate="5,10,15,20,30,50,100">
  ...
</p:dataTable>

我想保存每页行数的下拉框值。当用户更改值时,我将如何捕获事件?所以我可以读取并保存“5,10,15,20,30,50,100”值之一,以便下次用户返回此页面时自动出现。目前,它没有保存,所以每次(重新)加载页面时,它都会恢复到默认值“10”。

【问题讨论】:

    标签: jsf primefaces


    【解决方案1】:

    我有这样的简单解决方案

    <p:dataTable
    
    .....
    
    <p:ajax event="page" listener="#{yourBean.onPaginate}" />
    
    ...
     </p:dataTable>
    

    这是你的豆子

    public void onPaginate(PageEvent event)
        {
            String pageSizeParam = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("parameter name");
    
    ....
    

    使用“参数名称”,您可以检查 F12,网络选项卡 -> 有效负载

    【讨论】:

      【解决方案2】:

      上面写的(用 Primefaces 7.X 测试)的一个更简单的方法是简单地使用访问器方法。此解决方案的优点是可以设置实际的行数。否则,在我的情况下,我会在更改之前获得之前的行数......

      <p:dataTable
              .....
              paginator="true"
              paginatorPosition="bottom"
              paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
              currentPageReportTemplate="Total records: {totalRecords}, showing page {currentPage} of {totalPages}"
              rowsPerPageTemplate="25,50,100"
              rows="#{controller.rowsPerPage}"
              .....
          >
              .....
              .....
      </p:dataTable>
      

      bean 应该看起来像:

      @ViewScoped
      @Named
      public class Controller implements Serializable {
          private int rowsPerPage = 25; //default value
      
          public int getRowsPerPage() {
            return rowsPerPage;
          }
      
          /** Will be called each time the number or selected rows change */
          public void setRowsPerPage(int rows){
            this.rowsPerPage = rows; 
            // Do some other stuff, like using a cache to store the value
          }
      }
      

      我个人使用缓存来存储每个用户和实体类型的行数。

      【讨论】:

      • 您能说明一下您是如何使用缓存来存储值的吗?
      • 到我写这篇文章的时候,我已经改变了做这件事的方式。现在我将它存储在会话的 cookie 中
      【解决方案3】:

      我也在寻找解决方案,在阅读了这个帖子后,我发现有一个新的 Primefaces 功能可以让您保存数据表的状态。

      因此,对于 Primefaces v6.0.10+,您只需添加 multiViewState="true"

      请注意,这还将在每页的行旁边保存过滤器、排序、当前页面和选择。

      这里是该功能的官方演示链接:https://www.primefaces.org/showcase/ui/data/datatable/tableState.xhtml

      【讨论】:

        【解决方案4】:

        我将这个解决方案发布到另一个问题,我之所以分享它是因为我希望有人会发现它比 Daniel 的实现起来更简单(它仍然教会了我很多关于 JQuery 的知识!)

        我的解决方案是使用 Primefaces 5.2.x。

        我找到了一种非常简单的方法来实现它,我遇到的一个问题是当调用 onPaginate() 方法时,它没有最新的选定值。

        所以我这样做是为了确保您始终拥有最新的值,并且可以将其保存/加载到数据库或 cookie 或其他东西(我们保存到 cookie)。

        <p:dataTable
                .....
                paginator="true"
                paginatorPosition="bottom"
                paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                currentPageReportTemplate="Total records: {totalRecords}, showing page {currentPage} of {totalPages}"
                rowsPerPageTemplate="25,50,100"
                rows="#{controller.rowsPerPage}"
                .....
            >
                .....
                <p:ajax event="page" oncomplete="rowsPerPageUpdate()" />
                .....
        </p:dataTable>
        <p:remoteCommand name="rowsPerPageUpdate" actionListener="#{controller.onPaginate}" />
        

        然后我们的控制器看起来像这样:

        @Dependent
        @Named
        public class TableController implements Serializable {
            private String rowsPerPage = "25"; //default value
            .....
            public void onPaginate() {
                //save to the cookie
            }
            .....
        }
        

        基本上魔法发生在 remoteCommand 中,它会在 ajax 事件之后触发,以确保 controller.rowsPerPage 已正确更新。

        【讨论】:

        • 如果人们只是开始使用惰性模型。比所有这些解决方法简单得多
        【解决方案5】:

        你可以这样做:

        观点

        <h:form id="mainForm">
        
            <p:dataTable id="locationTable" value="#{datatableBean.list}" var="item"
                         paginator="true" widgetVar="dtVar"
                         rows="#{datatableBean.rows}" 
                         paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                         rowsPerPageTemplate="1,2,3,4,5,6">
                <p:column>
                    #{item.name}
                </p:column>
            </p:dataTable>
        
            <p:remoteCommand name="persistRows" action="#{datatableBean.saveRows}" process="@this" 
                             update="rows" global="false" />
        
            <h:outputText id="rows" value="#{datatableBean.rows}" />
        
            <script>
                jQuery(document).ready(function() {
                    dtVar.paginator.rppSelect.change(function() {
                        persistRows([{name: 'rows', value: this.value}]);
                    });
                });
            </script>
        </h:form>
        

        豆子

        import java.io.Serializable;
        import java.util.ArrayList;
        import java.util.List;
        import java.util.Map;
        import javax.annotation.PostConstruct;
        import javax.faces.bean.ManagedBean;
        import javax.faces.bean.SessionScoped;
        import javax.faces.context.FacesContext;
        
        @ManagedBean
        @SessionScoped
        public class DatatableBean implements Serializable {
        
            private int rows;
        
            private List<SimpleBean> list;
        
            @PostConstruct
            public void setup() {
                //default rows value
                rows = 2;
        
                list = new ArrayList<SimpleBean>();
                //ID and Name
                list.add(new SimpleBean(11, "A"));
                list.add(new SimpleBean(22, "B"));
                list.add(new SimpleBean(33, "C"));
            }
        
            public void saveRows(){
                FacesContext context = FacesContext.getCurrentInstance();
                Map map = context.getExternalContext().getRequestParameterMap();
                String rowsStr = (String) map.get("rows");
                rows = Integer.parseInt(rowsStr);
            }
        
            public int getRows() {
                return rows;
            }
        
            public void setRows(int rows) {
                this.rows = rows;
            }
        
            public List<SimpleBean> getList() {
                return list;
            }
        
            public void setList(List<SimpleBean> list) {
                this.list = list;
            }
        
        }
        

        这里的策略是扩展与分页器渲染的html select标签关联的onchange事件。为了便于完成这项任务,我在数据表 (dtVar) 中设置了 wigetVar,因为知道它是客户端 api,通过 dtVar.paginator.rppSelect 为我们提供了两个选择。

        现在,为了能够将这些选择的值发送到托管 bean,我们可以使用 remoteCommand。使用 remoteCommand 组件,我们可以将 javascript 参数发送到 managedbean。我已将 remoteCommand 命名为 persistRows 并通过调用它,我使用组件所需的模式指定了额外的参数:[{name: 'rows', value: this.value }] ([{name: 'nameOfTheVariable', value: 'valueOfTheVariable'}])。

        现在您可以使用该行属性做任何您想做的事情。

        【讨论】:

        • 谢谢。不太明白,能详细点吗?
        • 我的意思是,我试过了,但它不起作用,只要我刷新页面,它就会“忘记”每页的行数。
        • 我更新了问题以解释策略。我已经在 Primefaces 4 上测试了该示例代码,它按预期工作。如果解释不够,请向我们发送更多代码,以便我们更精确地模拟它。
        • 好的,谢谢。所以,在上面的代码中,rows 没有保存在任何地方,我需要保存它以便在另一个页面加载时恢复它?
        • 它保存在@SessionScoped 上。这就是为什么它应该在页面重新加载上工作。
        猜你喜欢
        • 2018-12-27
        • 1970-01-01
        • 2021-08-17
        • 1970-01-01
        • 2014-05-03
        • 2013-10-03
        • 2013-01-19
        • 2010-10-29
        • 2018-06-27
        相关资源
        最近更新 更多