即使 rendered 属性为 false,组件仍然会出现在组件树中

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

Mojarra 2.1.

我检查了 public void execute(FacesContext facesContext) throws FacesException class com.sun.faces.lifecycle.RestoreViewPhase 中的方法。现在,一旦通过调用 viewRoot = viewHandler.restoreView(facesContext, viewId); 恢复了视图,我们就拥有了来自先前请求的完整树(如果它是回发)。

我检查了那棵树(在调试器中手动遍历组件的 children 属性),发现复合组件声明如下:

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

都在那棵树上。尽管 #{bean.id} 被评估为 2,但它还是发生了。我预计唯一的 <utils:dateFilterItem /> 实例将在树中。

那么,我的问题是 rendered 属性是如何被 Mojarra 处理的?该属性是否影响唯一的渲染响应阶段?

RestoreView 阶段不使用呈现的属性。第一次评估是在 ApplyRequestValue 阶段。这是因为在 RestoreView 阶段没有应用请求值。因此,无法评估可能依赖于这些值的 rendered 属性。

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.

JSF 的组件树 知道 所有 组件,无论它们是否被渲染。这允许您 重新渲染 某个组件及其所有内部组件(通常与复选框等一起使用)。如果内部 - 尚未渲染的组件 - 在组件树中丢失,则使用render="outerComponent"render="outerComponent" 如果它们的 rendered 属性现在评估为真,则将无法显示内部组件。

为了完全避免将组件添加到该树中,您必须使用 JSTL-Tag,例如 <c:if > - 如果计算结果为 false,则组件根本不会添加到组件树中,因此 JSF 会在不知道某个组件的情况下开始处理树。

您可能还想阅读此 post,其中通过示例和更多详细信息解释了差异: JSTL in JSF2 Facelets... makes sense?