刷新 PrimeFaces 表单元素数据表(提供代码详细信息)

Refreshing PrimeFaces form element dataTable (code details provided)

我有搜索表单。单击“搜索”按钮后数据会刷新,但 dataTable 列不会(列仅在第二次单击按钮时刷新)。显然我做错了什么。动态列代码的灵感来自 PrimeFaces Showcase

myForm.xhtml:

<h:form id="MY_FORM">
    #{myBean.initBean()}
    ...
    <h:panelGrid id="main">
        <h:panelGrid id="buttons">
            <p:commandButton id="submitSearch"
                             value="#{msg['button.execute']}"
                             actionListener="#{myBean.submitSearch}"
                             update="resultPanel"/>
        </h:panelGrid>
    </h:panelGrid>

    <h:panelGrid id="resultPanel" border="0">
        <p:dataTable id="resultTable" var="result" value="#{myBean.searchResults}">
            <p:columns value="#{myBean.columns}" var="column" columnIndexVar="colIndex">
                <f:facet name="header">
                    <h:outputText value="#{column.header}" />
                </f:facet>
                <h:outputText value="#{result[column.property]}" />
            </p:columns>
        </p:dataTable>
    </h:panelGrid>
</h:form>

我从 myBean.initBean()myBean.submitSearch() 调用了列计算方法 createColumns(),结果相同(我发现它在调试器中工作正常)。

@ManagedBean("myBean")
@Scope(value = "session")
public class MyBean {
    private ArrayList<HashMap<String,Object>> searchResults;
    private List<ColumnModel> columns;
    ...
    public void initBean() {
        ...
        createColumns(selectedDates);
    }

    public void submitSearch() {
        ...
        ArrayList<HashMap<String, Object>> results = prpRepository.getSearchResultByParams(searchParams);
        createColumns(selectedDates);
    }

    private void createColumns(ArrayList<String> selectedDates){
        columns = new ArrayList<ColumnModel>();   
        columns.add(new ColumnModel("Name", "NAME"));
        columns.add(new ColumnModel("Amount", "AMOUNT"));

        for (int i = 0; i < selectedDates.size(); i++) {
            columns.add(new ColumnModel(selectedDates.get(i), "DATE" + i));
        }

        setColumns(columns);
    }

    public List<ColumnModel> getColumns() {
        return columns;
    }

    public void setColumns(List<ColumnModel> columns) {
        this.columns = columns;
    }
}

附加信息: 我正在使用:

我终于更好地使用调试器并找到了答案。解决方案是将 createColumns() 方法调用放入 getter getColumns() 列,因为它会在 submitSearch() 之前自动调用。我的问题在于对应用程序生命周期的理解。

问题是列在 org.primefaces.component.datatable.DataTabe

中只计算一次
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);
                    uiColumns.updateModel(); /* missed code */
                    for(int i=0; i < uiColumns.getRowCount(); i++) {
                        DynamicColumn dynaColumn = new DynamicColumn(i, uiColumns);
                        dynaColumn.setColumnKey(uiColumnsClientId + separator + i);
                        columns.add(dynaColumn);
                    }
                }
            }
       // }        
        return columns;
    }

您可以评论它并覆盖 class 文件, 或者在 createColumns 方法中找到 DataTable 对象并将 setColumns 设置为 NULL