1

最后,当数据表结构根据外部源定义时,我已经管理了如何在 JSF 中使用类似DOM的方法构建真正的动态表。具有动态列的 DataTable正是我所需要的)基本上,以下代码对我来说已经足够了:

<p:layoutUnit position="west">
    <!-- 2 -->
    <p:tree value="#{tableViewsPageBean.root}" var="node" dynamic="true" cache="false"
                                        selectionMode="single" selection="#{tableViewsPageBean.selectedNode}">
        <!-- 3 -->
        <p:ajax event="select" listener="#{tableViewsPageBean.onNodeSelect}"/>
        <p:treeNode id="treeNode">
            <h:outputText value="#{node}"/>
        </p:treeNode>
    </p:tree>
</p:layoutUnit>
<p:layoutUnit position="center">
    <h:panelGroup>
        <h:panelGroup rendered="#{tableViewsPageBean.isRegeneratable}">
            <p:commandButton value="#{fu:$(languageBean, 'REGENERATE')}"
                             action="#{dynamicTableViewBean.regenerate}"/>
        </h:panelGroup>
        <!-- 1 -->
        <h:panelGroup binding="#{dynamicTableViewBean.dataTableGroup}"/> 
    </h:panelGroup>
</p:layoutUnit>

但是有一个问题我目前不知道如何解决。如果你看一下上面的代码,你可以在注释中看到代表支持 bean 方法流的数字标记:

  1. binding="#{dynamicTableViewBean.dataTableGroup}"
  2. selection="#{tableViewsPageBean.selectedNode}"
  3. listener="#{tableViewsPageBean.onNodeSelect}"

这个顺序对我不好,因为h:panelGroup必须在用户更改树视图中的选择后定义绑定。简单地说,最好的流程是:

  1. selection="#{tableViewsPageBean.selectedNode}"(前 2 个)
  2. listener="#{tableViewsPageBean.onNodeSelect}"(之前 3 个)
  3. binding="#{dynamicTableViewBean.dataTableGroup}"(之前 1 个)

所以我可以构建一个尊重树中用户选择的数据表组件。那么这是一种强制执行上述方法的另一种顺序的方法吗?使用的 PrimeFaces 版本:3.2

提前致谢。非常感谢您的帮助。

4

2 回答 2

2

它在 JSP 上的旧 JSF 1.x 中以这种方式工作,但在 Facelets 上的 JSF 2.x 中不再如此。但是调用顺序应该无关紧要。只需将bindinggetter/setter 设置为普通的 getter/setter 并操作dataTableGroup侦听器方法的内部即可。毕竟是相同的对象引用。

public void onNodeSelect(NodeSelectEvent event) {
    dataTableGroup.getChildren().add(...);
    // ...
}

您只需要添加该update属性<p:ajax>,以便在 ajax 请求完成时真正更新绑定的面板组或其父面板组之一,否则您将有效地看到视图中没有任何变化。

例如

<h:form id="formId">
    ....
    <p:ajax event="select" listener="#{tableViewsPageBean.onNodeSelect}" update=":formId:groupId" />
    ...
    <h:panelGroup id="groupId" binding="#{dynamicTableViewBean.dataTableGroup}"/> 
    ...
</h:form>

顺便说一句,您知道 PrimeFaces 的<p:columns>组件吗?如果您想要的只是动态列,这可能是一个更好的解决方案。UIComponent在黑暗的 JSF 1.x 时代,这种解决方案并不存在,这就是为什么应用了笨拙的binding解决方法。

于 2012-05-02T16:20:57.777 回答
1

您不能强制绑定表达式在之后执行,因为它是 JSF 生命周期的一个特性 - 在请求处理的一开始就设置绑定(在“恢复视图”阶段)。
我还建议从动作侦听器(即 in#{tableViewsPageBean.onNodeSelect}和/或#{dynamicTableViewBean.regenerate})触发基于模型的树更新,因为它们是在“调用应用程序”阶段执行的(在提交的值已被转换、验证并应用于模型对象之后)只是在“渲染响应”之前。
您仍然可以使用从绑定表达式获得的 PanelGroup 引用,并在 Java 代码中对其子项进行操作。

于 2012-05-03T14:20:26.767 回答