问题描述
我认为我不得不使用非常旧的MyFaces 2.0.5版本,而EL的动态包含会导致很多问题,因此我将ui:fragment切换为静态包含
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
<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>
有了这个,它仍然抱怨重复的ID,因为我在这些源文件中使用了相同的ID.因此,即使rendered
应该也应该是false
,它仍然可以进入组件树.但是重复的ID是可以的.我可以解决这个问题,所以现在提交表单时,我遇到了这个异常
With this, it still complain about duplicate id because I use same id on couples of these source file. So it seems that even rendered
should be false
, it still make it to the component tree. However duplicate id is fine. 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
因此从异常中可以看到,它ListBoxFilter
是我想要的对象,因此仅包含ListBoxFilter.xhtml,但正在访问checkBoxFilters.xhtml
,因此出现错误.您知道如何解决此问题吗?
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. Any idea how to fix this issue please?
推荐答案
<ui:include>
不从UIComponent
扩展.这是一个标记处理程序.因此,它根本不支持rendered
属性.在标记文档中也没有列出.
The <ui:include>
doesn't extend from UIComponent
. It's a tag handler. It does thus not support the rendered
attribute at all. It's also nowhere listed in the tag documentation.
<ui:fragment>
确实是UIComponent
.因此,基本上,您最终会得到全部,这3个包含文件在视图构建期间包含在内,因此,这3个物理文件最终都落入JSF组件树中.只有通过<ui:fragment rendered>
有条件呈现的HTML输出.您仍然最终会从其中包含重复的组件ID,因为它们最终都在JSF组件树中.
<ui:fragment>
is indeed an 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. It's only the HTML output which is conditionally rendered via <ui:fragment rendered>
. You still end up with duplicate component IDs from those includes because they all end up in JSF component tree.
您应该使用像<c:if>
这样的标记处理程序而不是<ui:fragment>
有条件地构建JSF组件树.
You should be using a taghandler like <c:if>
instead of <ui:fragment>
to conditionally build the JSF component tree.
因此,从理论上讲,这应该适用于每个人:
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
但是,当#{filtersPopup}
是视图作用域的bean和/或使用<f:viewParam>
时,这有一些警告:
This has however some caveats when #{filtersPopup}
is a view scoped bean and/or when you're using <f:viewParam>
:
-
这至少需要Mojarra 2.1.18,否则JSF视图作用域的bean将无法还原.
This requires minimum Mojarra 2.1.18, otherwise JSF view scoped beans will fail to restore.
标记处理程序在视图构建期间运行.因此,此后运行的诸如<f:viewParam>
之类的东西将根本无法工作.您需要回退到通过ExternalContext
手动获取HTTP请求参数.
Taghandlers run during view build time. So things which runs thereafter like <f:viewParam>
won't work at all. You'd need to fall back to manually grabbing HTTP request parameters via ExternalContext
.
另请参见:
- JSF2 Facelets中的JSTL ...有意义吗?
- JSTL in JSF2 Facelets... makes sense?
See also:
这篇关于动态ui:include和ui:fragment:呈现为false的组件仍在组件树中生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!