动态ui:包含ui:fragment:具有呈现false的组件仍然在组件树内部生成

Tha*_*ham 1 jsf myfaces jsf-2

我强行使用一个非常旧版本的MyFaces 2.0.5我认为,动态包含EL导致这么多问题,所以我切换到静态包含ui:fragment

<ui:fragment rendered="#{filtersPopup.filterFileName == 'checkBoxFilters'}">
    checkBoxFilters
    <ui:include src="/analytics/checkBoxFilters.xhtml" rendered="#{filtersPopup.filter != null}"/>
</ui:fragment>
<ui:fragment rendered="#{filtersPopup.filterFileName == 'DateRelativeFilter'}">
    DateRelativeFilter
    <ui:include src="/analytics/DateRelativeFilter.xhtml" rendered="#{filtersPopup.filter != null}"/>
</ui:fragment>
<ui:fragment rendered="#{filtersPopup.filterFileName == 'listboxFilter'}">
    listboxFilter
    <ui:include src="/analytics/listboxFilter.xhtml" rendered="#{filtersPopup.filter != null}"/>
</ui:fragment>
Run Code Online (Sandbox Code Playgroud)

有了它,它仍然抱怨重复的id,因为我在这些源文件的夫妇上使用相同的id.所以它似乎rendered应该是false,它仍然使它成为组件树.但重复的ID很好.我可以轻松解决这个问题,所以现在当我提交表单时,我得到了这个例外

 /analytics/checkBoxFilters.xhtml at line 24 and column 118 value="#{filtersPopup.filter.groups}": Property 'groups' not found on type ListBoxFilter
Run Code Online (Sandbox Code Playgroud)

所以从异常中可以看出,它ListBoxFilter是我想要的对象,所以只包含ListBoxFilter.xhtml,但正在访问checkBoxFilters.xhtml因此错误.知道如何解决这个问题吗?

Bal*_*usC 10

<ui:include>不会延长UIComponent.它是一个标签处理程序.因此它根本不支持该rendered属性.它也没有在标签文档中列出.

<ui:fragment>确实是一个UIComponent.所以基本上你最终会在视图构建时间内包含所有这3个包含文件,因此所有3个文件最终都在JSF组件树中.它只是通过有条件地呈现的HTML输出<ui:fragment rendered>.您仍然最终会从这些包含重复的组件ID,因为它们最终都在JSF组件树中.

您应该使用taghandler <c:if>而不是<ui:fragment>有条件地构建JSF组件树.

所以,从理论上讲,这应该适用于每一个:

<c:if test="#{filtersPopup.filterFileName == 'checkBoxFilters'}">
    checkBoxFilters
    <c:if test="#{filtersPopup.filter != null}">
        <ui:include src="/analytics/checkBoxFilters.xhtml" />
    </c:if>
</c:if>

... etc
Run Code Online (Sandbox Code Playgroud)

然而,当#{filtersPopup}一个视图范围的bean和/或你正在使用时,这有一些警告<f:viewParam>:

  1. 这需要最小的Mojarra 2.1.18,否则JSF视图范围的bean将无法恢复.

  2. Taghandlers在视图构建期间运行.因此,之后运行的东西<f:viewParam>根本不起作用.您需要回退到手动抓取HTTP请求参数ExternalContext.

也可以看看: