Jsf 2.0-xhtml included always even if rendered

2019-02-11 06:00发布

问题:

I have a home page xhtml where i am including 3 child xhtml based on conditions. The issue i am facing is , whatever be the scenario,Book.xhtml always gets invoked. I changed the rendered condition to false or move out to another condition, but the file always gets invoked Due to which its backing bean also is invoked causing unwanted overhead. Please provide me a solution

<ui:composition template="/xhtml/baseLayout.xhtml">
    <ui:define name="browserTitle">
        <h:outputText value="HOME PAGE" />
    </ui:define>
    <ui:define name="header">
        <ui:include src="/xhtml/header.xhtml" />
    </ui:define>
    <ui:define name="bodyContent">

        <h:panelGrid width="100%"
            rendered="#{pogcore:isRoleAuthorized(BUNDLE.SUPER)}"  >
            <ui:include src="/xhtml/SuperUser.xhtml"  />
        </h:panelGrid>
        <h:panelGrid width="100%"
            rendered="#{pogcore:isRoleAuthorized(BUNDLE.MAINTENANCE)}" >
            <ui:include src="/xhtml/Maintenance.xhtml" />
        </h:panelGrid>

        <h:panelGrid width="100%"
            rendered="#{pogcore:isRoleAuthorized(BUNDLE.PRINT)}">
            <ui:include src="/xhtml/Book.xhtml" />
        </h:panelGrid>

    </ui:define>
</ui:composition>

回答1:

This is happening due to lifecycle of jsf. JSF UIComponents are evaluated during view render time where as jstl tags are evaluated at build time.

So when you use rendered attribute of h:panelGrid it is too late to not invoke managed beans under the included page. To resolve this try having conditions using jstl tag, the following should work for you.

<c:if test="#{bean.yourCondition}">
    <h:panelGrid width="100%"> 
        <h:outputText value="#{bean.yourCondition}"/> <!--if this is not getting printed there is smtg wrong with your condition, ensure the syntax, the method signature is correct-->
        <ui:include src="/xhtml/Book.xhtml" /> 
    </h:panelGrid>
</c:if> 
<c:if test="#{!bean.yourCondition}"> 
    <h:outputText value="#{bean.yourCondition}"/> <!--This should print false-->
</c:if>

The document below describes the details of jstl and jsf lifecycle.

http://www.znetdevelopment.com/blogs/2008/10/18/jstl-with-jsffacelets/

Check the following document to see another way to solve this without using jstl tags.

http://pilhuhn.blogspot.com/2009/12/facelets-uiinclude-considered-powerful.html



回答2:

Do this:

  • Always include the sub pages
  • Put the panelGrid (with the rendered) inside the page that you always include

Why ? Because the inclusion is performed before the rendered is evaluated.