I have a problem understanding the JSF Phases. I have the followed problem.
On my main page i create a panelGroup, and includes a xhtml dynamicaly.
<h:panelGroup id="padding">
<ui:include src="#{navigationHandler.currentPage}" />
</h:panelGroup>
In my menubar i have some code like this:
<p:submenu label="#{translator.menuentry_insured}">
<p:menuitem value="#{translator.menuentry_add_insured}" actionListener="#{navigationHandler.addInsured}" update=":padding" />
<p:menuitem value="#{translator.menuentry_search_insured}" actionListener="#{navigationHandler.searchInsured}" update=":padding"/>
</p:submenu>
When I click on the menuitem, first the "currentPage" method is called, returning the page currently active. After that, the actionListener is called, setting the page to the new page. If I click again on the same link, then the correct page is shown.
I know the problem is in the JSF lifecycle ("restore view" phase before "开发者_开发知识库invoke application" phase), but I don't know how to solve this.
Here is a output from my own PhaseListener, just for debugging purpose:
BEFORE: RESTORE_VIEW 1
Using current page: addInsured.xhtml
AFTER: RESTORE_VIEW 1
BEFORE: APPLY_REQUEST_VALUES 2
AFTER: APPLY_REQUEST_VALUES 2
BEFORE: PROCESS_VALIDATIONS 3
AFTER: PROCESS_VALIDATIONS 3
BEFORE: UPDATE_MODEL_VALUES 4
AFTER: UPDATE_MODEL_VALUES 4
BEFORE: INVOKE_APPLICATION 5
Setting current page to searchInsured.xhtml
AFTER: INVOKE_APPLICATION 5
BEFORE: RENDER_RESPONSE 6
AFTER: RENDER_RESPONSE 6
Is there any solution? What I am doing wrong?
I believe you are confusing JSF Components (usually seen with prefixs of 'h', 'f', 'p') with facelet components (usually seen with prefix of 'ui'). They aren't the same thing. JSF Component usually become part of the tree and participate in the JSF phases. Facelet component only exist during RESTORE_VIEW
. I usually think of facelet components as preprocessors. They normally generate JSF components.
In your example, <ui:include src="#{navigationHandler.currentPage}" />
is replaced with whatever JSF Components specified in the source file referred to by navigationHandler.currentPage
at the time of RESTORE_VIEW
. After RESTORE_VIEW
, there is no more <ui:include />
, so it isn't re-evaluated and doesn't update.
During INVOKE_APPLICATION
, navigationHandler.currentPage
is updated, but the component tree is still the same. If you could force a self redirect during INVOKE_APPLICATION
, then the lifecycle would be restarted and <ui:include src="#{navigationHandler.currentPage}"/>
would be re-evaluated.
精彩评论