简体   繁体   English

动态 ui:include 和 ui:fragment: 渲染为 false 的组件仍然在组件树内部

[英]dynamic ui:include with ui:fragment: component with rendered false still make inside component tree

I am force to use a very old version of MyFaces 2.0.5 I think, and dynamic include with EL cause so much problem, so I switch to static include with ui:fragment我认为我不得不使用非常旧版本的 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>

With this, it still complain about duplicate id because I use same id on couples of these source file.有了这个,它仍然会抱怨重复的 id,因为我在这些源文件中使用了相同的 id。 So it seems that even rendered should be false , it still make it to the component tree.所以看起来即使rendered应该是false ,它仍然会进入组件树。 However duplicate id is fine.但是重复的 id 很好。 I can fix that easy, so now when I submit form, I got this exception我可以轻松解决这个问题,所以现在当我提交表单时,我收到了这个异常

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

so as you can see from the exception, it ListBoxFilter is the object I want, so only include ListBoxFilter.xhtml, but is being accessed checkBoxFilters.xhtml hence the error.所以你可以从异常中看到,它ListBoxFilter是我想要的对象,所以只包含 ListBoxFilter.xhtml,但正在访问checkBoxFilters.xhtml因此错误。 Any idea how to fix this issue please?知道如何解决这个问题吗?

The <ui:include> doesn't extend from UIComponent . <ui:include>不是从UIComponent扩展的。 It's a tag handler.这是一个标签处理程序。 It does thus not support the rendered attribute at all.因此它根本不支持rendered属性。 It's also nowhere listed in the tag documentation .它也没有在标签文档中列出。

<ui:fragment> is indeed an UIComponent . <ui:fragment>确实是一个UIComponent So basically you end up with all those 3 include files being included during view build time and thus all 3 physically end up in JSF component tree.所以基本上你最终会在视图构建期间包含所有这 3 个包含文件,因此所有 3 个文件最终都在 JSF 组件树中。 It's only the HTML output which is conditionally rendered via <ui:fragment rendered> .它只是通过<ui:fragment rendered>有条件地呈现的 HTML 输出。 You still end up with duplicate component IDs from those includes because they all end up in JSF component tree.您仍然会得到来自那些包含的重复组件 ID,因为它们都以 JSF 组件树结束。

You should be using a taghandler like <c:if> instead of <ui:fragment> to conditionally build the JSF component tree.您应该使用像<c:if>这样的标记处理程序而不是<ui:fragment>来有条件地构建 JSF 组件树。

So, theoretically, this should do for each of them:所以,理论上,这应该对他们每个人都做:

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

... etc

This has however some caveats when #{filtersPopup} is a view scoped bean and/or when you're using <f:viewParam> :但是,当#{filtersPopup}是视图范围的 bean 和/或当您使用<f:viewParam>时,这有一些警告:

  1. This requires minimum Mojarra 2.1.18, otherwise JSF view scoped beans will fail to restore.这需要最低 Mojarra 2.1.18,否则 JSF 视图范围的 bean 将无法恢复。

  2. Taghandlers run during view build time.标签处理程序在视图构建期间运行。 So things which runs thereafter like <f:viewParam> won't work at all.所以像<f:viewParam>这样之后运行的东西根本不起作用。 You'd need to fall back to manually grabbing HTTP request parameters via ExternalContext .您需要回退到通过ExternalContext手动获取 HTTP 请求参数。

See also:另见:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM