JSF: Respecting a component binding method after UI-driven events are processed in backing beans?

左心房为你撑大大i 提交于 2019-12-24 15:49:27

问题


Finally I've managed how to build a true dynamic table with the DOM-like approach in JSF when the data table structure is defined according to an external source. ( DataTable with dynamic columns exactly what I need) Basically, the following code is quite enough for me:

<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>

But there is a problem I currently do not know how to solve. If you take a look at the code above, you can see the numeric markers in the comments that represent the flow of the backing beans methods:

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

This order is not good for me, because the binding of the h:panelGroup must be defined after a user changed the selection in the tree view. Simply saying, the very best flow would be:

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

so I could build a data table component respecting the user selection in the tree. So is it a way to force another order of executing the methods above? PrimeFaces version used: 3.2

Thanks in advance. Your help is appreciated a lot.


回答1:


It worked that way in old JSF 1.x on JSP, but not anymore in JSF 2.x on Facelets. But the invocation order should not matter. Just make the binding getter/setter a normal getter/setter and manipulate the dataTableGroup inside the listener method instead. It's after all the same object reference.

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

You only need to add the update attribute to <p:ajax> in order to really update the bound panelgroup or one of its parents when the ajax request completes, otherwise you will effectively see no change in the view.

E.g.

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

By the way, are you aware of PrimeFaces' <p:columns> component? It may be a better solution if all you want is dynamic columns. That solution didn't exist in flavor of any UIComponent back in the dark JSF 1.x ages, that's why the awkward binding workaround was been applied.




回答2:


You cannot force binding expression to be executed afterwards, because it's a feature of JSF lifecycle - to set bindings at the very beginning of request processing (during phase "Restore View").
I would also recommend to trigger model-based tree updates from action listeners (i.e. in #{tableViewsPageBean.onNodeSelect} and/or #{dynamicTableViewBean.regenerate}), because they are executed on phase "Invoke Application" (after submitted values have been converted, validated, and applied to the model objects) just before "Render Response".
You can still use PanelGroup's reference obtained from binding expression and manipulate with its children in Java code.



来源:https://stackoverflow.com/questions/10384959/jsf-respecting-a-component-binding-method-after-ui-driven-events-are-processed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!