我强迫使用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>
有了这个,它仍然抱怨重复的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
从异常中可以看出,ListBoxFilter
是我想要的对象,所以只包含ListBoxFilter.xhtml,但是被访问checkBoxFilters.xhtml
因此出错。知道如何解决这个问题吗?
答案 0 :(得分:10)
<ui:include>
不会从UIComponent
延伸。它是一个标签处理程序。因此它根本不支持rendered
属性。它也没有列在the tag documentation中。
<ui:fragment>
确实是UIComponent
。所以基本上你最终会在视图构建时间内包含所有这3个包含文件,因此所有3个文件最终都在JSF组件树中。它只是通过<ui:fragment rendered>
有条件地呈现的HTML输出。您仍然会从这些包含重复的组件ID,因为它们都以JSF组件树结束。
您应该使用<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
当#{filtersPopup}
是视图范围的bean和/或当您使用<f:viewParam>
时,这有一些警告:
这需要最小的Mojarra 2.1.18,否则JSF视图范围的bean将无法恢复。
Taghandlers在视图构建期间运行。因此,像<f:viewParam>
这样的事情根本不起作用。您需要回退到通过ExternalContext
手动抓取HTTP请求参数。