jsfjsf-2rendered-attribute

Components still end up in component tree even when rendered attribute is false


Mojarra 2.1.

I checked the method public void execute(FacesContext facesContext) throws FacesException in the class com.sun.faces.lifecycle.RestoreViewPhase. Now, once the view's restored by the invokation viewRoot = viewHandler.restoreView(facesContext, viewId); we have the compelete tree from the previous request (if it's a postback).

I checked that tree (manually iterate through the children properties of the components in a debugger) and found that the composite components, declared as follows:

<h:panelGroup rendered="#{bean.id == 1}">
    <utils:dropDownListFilterItem  />
</h:panelGroup>
<h:panelGroup rendered="#{bean.id == 2}">
    <utils:dateFilterItem />
 </h:panelGroup>
 <h:panelGroup rendered="#{bean.id == 3}">
    <utils:fieldFilterItem />
</h:panelGroup>

were all in that tree. It happaned in spite of the fact that #{bean.id} was evaluated to 2. I expceted that the only <utils:dateFilterItem /> instance would be in the tree.

So, my question is how the rendered attribute is handled by Mojarra? Is the attribute infuences the only render-responces phase?


Solution

  • The rendered attribute is not used during the RestoreView-Phase. The first time it is evaluated is in the ApplyRequestValue-Phase. This is because during the RestoreView-Phase there are no Request Values applied. Thus the rendered-attribute which might depend on these values cannot be evaluated.

    were all in that tree. It happaned in spite of the fact that #{bean.id} was evaluated to 2. I expceted that the only instance would be in the tree.

    The component tree of JSF is aware of all components, no matter if they are rendered or not. This allows you to rerender a certain component with all it's inner components (often used with checkboxes etc.) If the inner - not yet rendered components - would be missing inside the component tree, the usage of render="outerComponent" would not be able to show the inner components if their rendered-attribute now evaluates to true.

    To avoid a component beeing added to that tree at all, you have to use a JSTL-Tag such as <c:if > - if this evaluates to false, the component would not be added to the component tree at all, so JSF would start processing the tree without knowing about a certain component.

    You may also want to read this post, where the difference is explained with examples and much more detail: JSTL in JSF2 Facelets... makes sense?