具有可变列和特定可编辑单元格的 PrimeFaces 数据表

PrimeFaces dataTable with variable columns and specific editable cells

我需要创建一个 table,其中 headers 列表来自模型。 table 内容也存储在模型中,p:dataTable 循环数据以根据列名显示内容。

问题是我需要制作一些特定的单元格 editable。对于输出数据,没有问题,因为我使用模型方法,该方法同时采用实体和列名以及 return 基于列名的实体的正确信息。问题出在我不知道如何在实体中设置的 editable 单元格的输入上。

<p:dataTable id="processTable"  var="entity" value="#{home.process.headerEntities}" tableStyle="width:auto" draggableColumns="true" editable="true" editMode="cell">

    <p:columns value="#{home.process.columns}" var="columnHead" >

        <f:facet name="header">
            <h:outputText value="#{columnHead}"/>
        </f:facet>

        <p:cellEditor>
            <f:facet name="output">
                <h:outputText value="#{home.process.getData(entity, columnHead)}" />
            </f:facet>
            <f:facet name="input">
                <p:inputText value="#{home.process.getData(entity, columnHead)}" rendered="#{home.process.isEditable(columnHead)}"  style="width:100%" />
            </f:facet>
        </p:cellEditor>


    </p:columns>

</p:dataTable>

After change based on BEST ANSWER

<p:dataTable id="processTable"  var="entity" value="#{home.process.headerEntities}" tableStyle="width:auto" draggableColumns="true" editable="true" editMode="cell">

                <p:columns value="#{home.process.columns}" var="columnHead" >

                    <f:facet name="header">
                        <h:outputText value="#{columnHead}"/>
                    </f:facet>

                    <p:cellEditor>
                        <f:facet name="output">
                            <h:outputText value="#{entity[home.process.columnPropertyMap[columnHead]]}" />
                        </f:facet>
                        <f:facet name="input">
                            <p:inputText value="#{entity[home.process.columnPropertyMap[columnHead]]}" rendered="#{home.process.isEditable(columnHead)}"  style="width:100%" />
                        </f:facet>
                    </p:cellEditor>


                </p:columns>

            </p:dataTable>

输入组件的值必须绑定到可写值表达式。你所拥有的是一个直接的 getter 方法调用,因此本质上是 read-only。这确实行不通。您需要指定一个 属性 名称的 #{entity}。您可以使用大括号表示法将 属性 名称指定为变量,例如 #{entity[propertyName]}.

所以,基本上:

<p:dataTable value="#{bean.entities}" var="entity" editable="true" editMode="cell">
    <p:columns value="#{bean.propertyNames}" var="propertyNames">
        <p:cellEditor>
            <f:facet name="output">
                #{entity[propertyName]}
            </f:facet>
            <f:facet name="input">
                <p:inputText value="#{entity[propertyName]}" />
            </f:facet>
        </p:cellEditor>
    </p:columns>
</p:dataTable>

至于列 header,而是将其重构为 Map<String, String>,其中键是 propertyName,值是 header。

        <f:facet name="header">
            #{bean.columnHeaders[propertyName]}
        </f:facet name="header">

或者更好的是,使用普通的 i18n 资源包,其中 propertyName 代表包密钥的一部分。

        <f:facet name="header">
            #{bundle['table.column.header.' += propertyName]}
        </f:facet name="header">

至于可编辑检查,而是将 propertyNameeditable 包装在另一个 bean 中(如果您不想使用 i18n 包,也可能 columnHeader ),例如Field 然后像下面这样使用:

    <p:columns value="#{bean.fields}" var="field">
        <p:cellEditor>
            <f:facet name="output">
                #{entity[field.propertyName]}
            </f:facet>
            <f:facet name="input">
                <p:inputText value="#{entity[field.propertyName]}" rendered="#{entity[field.editable]}" />
            </f:facet>
        </p:cellEditor>
    </p:columns>

总而言之,它只是归结为准备和提供视图期望的正确模型。这样就不需要 getData() 了。