2

我正在使用 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()总是给出空字符串。

4

1 回答 1

9

你错了:

  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. 因为你支持p:columns你,所以#{datatableBean.table}你应该已经拥有你试图从 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> 

在支持 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将 orderer 和 widths 存储到 db。

于 2014-02-03T19:23:59.870 回答