【问题标题】:how to get primefaces datatable columns order and width from ManagedBean如何从 ManagedBean 获取 primefaces 数据表列的顺序和宽度
【发布时间】:2014-02-27 04:28:12
【问题描述】:

我正在使用 primefaces 4.0,JSF Mojarra 2.2.2 这是我的数据表代码:

<p:dataTable id="tabexam"
             paginatorPosition="bottom"
             var="exam"
             value="#{dyna.examViewDataModel}"
             widgetVar="examTable"
             emptyMessage="aucun résultat trouvé pour votre recherche"
             paginator="true"
             rows="40" 
             selection="#{dyna.selectedExamen}"
             filteredValue="#{dyna.filteredexams}"
             selectionMode="single"
             resizableColumns="true"  
             draggableColumns="true"
             paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"  
             rowsPerPageTemplate="40,80,120">

<p:columns value="#{datatableBean.table}"
           var="column"
           headerText="#{column.userListname}"
           rendered="#{column.visible}"
           resizable="#{column.resizable}"
           width="#{column.width}"
           columnIndexVar="colIndex">

   <h:panelGroup>
             <p:outputLabel value="#{column.dbname}" styleClass="fonty"/>
   </h:panelGroup>

 </p:columns>

</p:dataTable>

到目前为止我已经尝试过,但是我在控制台中得到了 getHeaderText 的空字符串和空宽度,我想知道我错过了什么

UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
    DataTable tabler = (DataTable) view.findComponent(":form1:tabexam");
    List<UIColumn> coler = tabler.getColumns();

    for (int i = 0; i < coler.size(); i++) {

        System.out.println("/////////////////");
        System.out.println(coler.get(i).getValueExpression("headerText").getValue(FacesContext.getCurrentInstance().getELContext()));
        System.out.println(coler.get(i).getHeaderText());
        System.out.println(coler.get(i).isRendered());
        System.out.println(coler.get(i).isResizable());
        System.out.println(coler.get(i).getWidth());
        System.out.println("/////////////////");

    }
 System.out.println(coler.size());

请注意,coler.size() 给出了数据表上显示的列数。 但coler.get(i).getHeaderText() 总是给出空字符串。

【问题讨论】:

    标签: jsf-2 primefaces datatable dynamic-columns


    【解决方案1】:

    你错了:

    1. 不要将p:column 嵌套在p:columns
    2. DataTable.getColumns 没有返回您所期望的:

      public List<UIColumn> getColumns() {
          if(columns == null) {
              columns = new ArrayList<UIColumn>();
              FacesContext context = getFacesContext();
              char separator = UINamingContainer.getSeparatorChar(context);
      
              for(UIComponent child : this.getChildren()) {
                  if(child instanceof Column) {
                      columns.add((UIColumn) child);
                  }
                  else if(child instanceof Columns) {
                      Columns uiColumns = (Columns) child;
                      String uiColumnsClientId = uiColumns.getClientId(context);
      
                      for(int i=0; i < uiColumns.getRowCount(); i++) {
                          DynamicColumn dynaColumn = new DynamicColumn(i, uiColumns);
                          dynaColumn.setColumnKey(uiColumnsClientId + separator + i);
                          columns.add(dynaColumn);
                      }
                  }
              }
          }
      
          return columns;
      }
      

    这会返回一个合成模拟:每列仅columnKey,并且如您所说,正确的列数。

    一般来说,p:columns 是一个组件,当您从控制器层访问它时,您必须引用它的 DECLARATION(单个组件)而不是它的 REPRESENTATION(多列)

    1. 既然你用你的#{datatableBean.table} 支持p:columns,你应该已经以逆向工程的方式获得了你试图从DataTable 组件获取的所有信息。

    更新

    哦,现在我知道你想做什么了。您必须为此使用事件侦听器。

    来自 PF 展示:

    <p:dataTable var="car" value="#{tableBean.carsSmall}" widgetVar="cars" draggableRows="true">  
    
        <p:ajax event="colReorder" listener="#{tableBean.onColReorder}" update=":some:component" />  
    
        <p:ajax event="colResize" listener="#{tableBean.onColResize}" update=":some:component"/>    
    
        <!-- columns here -->  
    </p:dataTable> 
    

    在 backing bean 中监听这些事件并维护这些信息应该可以解决您的问题

    更新 2

    哇,一点都不简单。

    由于动态列调整大小的 Primefaces 错误(至少对于我的尝试而言)和不完整的列重新排序事件实现,结果如下:

    <h:form id="form">
        <h:panelGroup id="model">
            <ui:repeat var="column2" value="#{testBean.columnList2}">
                <div>#{column2.title} - #{column2.width}</div>
            </ui:repeat>
        </h:panelGroup>
    
        <p:dataTable var="elem" value="#{testBean.elementList}" resizableColumns="true" draggableColumns="true">
            <p:ajax event="colReorder" listener="#{testBean.onColumnReorder}" update=":form:model" />  
            <p:ajax event="colResize" listener="#{testBean.onColumnResize}" update=":form:model"/>  
    
            <c:forEach var="column" items="#{testBean.columnList}">
                <p:column headerText="#{column.title}" rendered="#{column.visible}" width="#{column.width}">
                    <f:attribute name="myCol" value="#{column}"/>
                    <span>#{elem[column.property]}</span>
                </p:column>
            </c:forEach>
        </p:dataTable>
    </h:form>
    

    还有这个豆子:

    @ManagedBean
    @ViewScoped
    public class TestBean implements Serializable
    {
        private static final long serialVersionUID = 1L;
    
        private List<MyColumn> columnList;
        private List<MyColumn> columnList2;
        private List<MyElement> elementList;
    
        public class MyColumn
        {
            private String title;
            private String property;
            private boolean visible = true;
            private boolean resizable = true;
            private int width = 100;
    
            public MyColumn(String title, String property, boolean visible, boolean resizable, int width)
            {
                super();
                this.title = title;
                this.property = property;
                this.visible = visible;
                this.resizable = resizable;
                this.width = width;
            }
    
            // getters and setters
        }
    
        public class MyElement
        {
            private String code;
            private String name;
            private String type;
    
            public MyElement(String code, String name, String type)
            {
                super();
                this.code = code;
                this.name = name;
                this.type = type;
            }
    
            // getters and setters
        }
    
        @PostConstruct
        public void init()
        {
            columnList = new ArrayList<>();
            columnList.add(new MyColumn("element code", "code", true, true, 100));
            columnList.add(new MyColumn("element name", "name", true, true, 100));
            columnList.add(new MyColumn("element type", "type", true, true, 100));
    
            columnList2 = new ArrayList<>(columnList);
    
            elementList = new ArrayList<>();
            elementList.add(new MyElement("001", "foo", "normal"));
            elementList.add(new MyElement("002", "bar", "strange"));
            elementList.add(new MyElement("003", "xyz", "normal"));
            elementList.add(new MyElement("004", "abc", "nothing"));
        }
    
        public void onColumnResize(ColumnResizeEvent event)
        {
            UIColumn column = event.getColumn();
            int width = event.getWidth();
    
            UIComponent colComponent = (UIComponent) column;
            MyColumn myCol = (MyColumn) colComponent.getAttributes().get("myCol");
    
            myCol.setWidth(width);
        }
    
        public void onColumnReorder(AjaxBehaviorEvent event)
        {
            DataTable table = (DataTable) event.getSource();
    
            columnList2.clear();
    
            for(UIColumn column : table.getColumns())
            {
                UIComponent colComponent = (UIComponent) column;
    
                MyColumn myCol = (MyColumn) colComponent.getAttributes().get("myCol");
                columnList2.add(myCol);
            }
        }
    
        // getters and setters
    
    }
    

    更新代码,您可以在columnList2 中找到有序列。现在也显示在表格中。 现在您可以使用columnList2 将排序和宽度存储到db。

    【讨论】:

    • 我明白了,但是#{datatableBean.table} 只是我自己创建的一个ColumnModel,所以你建议我需要将Columns 绑定到一个requestScoped bean,然后我就可以在拖动、宽度等之后获取对数据表列顺序所做的更改。
    • Michele 是聆听拖放操作的绝妙方式。我已经对其进行了测试,它就像一个魅力" " 但我真正的问题是如何在拖放后获得最终的列顺序。(例如:在拖动之前:1/car,2/ model,3/year ; 拖拽后 : 1/car,3/year,2/model) 所以我需要把它保存到数据库中,这样当用户连接时,得到相同的列顺序。
    • 谢谢,但这是 Primefaces 的优点,不是我的 :) 您应该在 bean 中维护一个模型,并根据事件的变化更新该模型。也许相同的 List 适合。您可以选择是否要在每个事件上在 db 上提交此模型,或者在用户按下按钮时提交。
    • 我已经对此进行了测试,但是在调用 onColumnReorder() 之后,我在 columnList.get(1).getTitle() 上获得了 NPE;
    • 精巧整洁:)
    猜你喜欢
    • 2015-04-09
    • 2014-12-23
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 2013-05-07
    相关资源
    最近更新 更多