p:dataTable 在过滤和返回页面后不呈现 header

p:dataTable doesn't render header after filtering and paging back

我需要在页面之间导航时保​​留过滤后的数据。在数据 table 的过滤单元格中输入数据后,它会显示正确的过滤行。如果过滤器单元格中最后输入的数据与要显示的任何数据行都不匹配,并且当我导航到另一个页面并返回 return 时 - 列 headers 和过滤器单元格不会呈现。仅显示分页器。如果过滤器单元格中最后输入的数据与某些数据行匹配,则它可以正常工作。如果我不离开包含数据 table.

的页面,它也能正常工作

jsf代码:

<p:dataTable id="tableId" var="intance" widgetVar="instance" 
        value="#{model.rows}" filteredValue="#{model.filteredRows}" 
        sortBy="#{model.sortBy}" sortMode="multiple" rows="5" 
        rowsPerPageTemplate="5, 15" paginator="true" paginatorPosition="bottom">
    <p:ajax event="filter" listener="#{model.onFilter}"/>
    <p:ajax event="sort" listener="#{model.onSort}"/>
    <p:columns id="columnId" value="#{instance.columnsData}" 
        var="instanceColumn" columnIndexVar="ind" rendered="true" 
        sortBy="#{instance.columnsData[ind]}" 
        filterBy="#{instance.columnsData[ind]}" filterMatchMode="contains" 
        filterValue="#{model.tableFilters[''.concat(ind)]}" 
        headerText="#{labels[ind]}">
            <h:outputText value="#{instance.columnsData[ind]}"/>
    </p:columns>
</p:dataTable>

java代码:

public class Model {

    private List<MyRow> filteredRows;

    private List<MyRow> rows;

    private Map<String, String> tableFilters;

    public void onFilter(FilterEvent event) {
        tableFilters = event.getFilters();
        if (MapUtils.isEmpty(tableFilters)) {
            filteredRows = null;
        }
    }

    public void List<MyRow> getRows() {
        //retreve data from service and transform to List<MyRow>)
        return rows;
    }

    /* getters and setter */
}


public class MyRow {
    private List<Object> columnsData;
    /* getters and setters */
}

有什么想法吗?该代码对我来说看起来不错并且应该可以工作。我使用 primefaces 3.5.

谢谢

问题的根源是 p:columnsvalue="#{instance.columnsData}"。在这种情况下使用 p:dataTable#{instance} 变量是错误的。

首次加载页面且 #{model.rows} 不是 empty 时工作正常。

#{model.rows} 不是 empty 并且当我们在过滤器单元格中键入一个与 #{model.rows} 中的数据不匹配的值时,没有显示行,只有列 headers 和过滤器单元格无论如何都会呈现,因为仅部分呈现数据内容(table headers 和过滤器单元格在呈现页面期间呈现)。

当我们导航到另一个页面,然后 return 返回到我们在数据 table 中过滤行的页面时,会出现一个新的完整页面呈现。所以在这种情况下(#{model.filteredRows} 不是 null),#{model.rows} 包含多少数据并不重要。 #{model.filteredRows} 将用于呈现数据 table 内容。因此,当 primefaces 呈现数据 table 时,在我的例子中根本没有要呈现的数据,因为 #{model.filteredRows}empty 而不是 null

因为我在 p:columns 中使用 p:dataTable#{instance} 变量,p:columns 将不呈现任何列 - 没有要显示的列 headers 和过滤单元格.

解决方案:使用separate field包含列信息。

//edited class Model
public class Model {
    //add a field that contains columns count. For example:
    private List<Integer> columns = Collections.nCopies(5, 1);

   //another fields
}

需要使用value="#{model.columns}"而不是value="#{instance.columnsData}"

<p:columns id="columnId" value="#{model.columns}" 
    var="instanceColumn" columnIndexVar="ind" rendered="true" 
    sortBy="#{instance.columnsData[ind]}" 
    filterBy="#{instance.columnsData[ind]}" filterMatchMode="contains" 
    filterValue="#{model.tableFilters[''.concat(ind)]}" 
    headerText="#{labels[ind]}">
    <h:outputText value="#{instance.columnsData[ind]}"/>
</p:columns>