Hat*_*mam 22 jsf conditional rendered-attribute jsf-2 uiinclude
我知道我们不能重复在同一个视图树中我们拥有的任何组件的ID.
我有一个页面,其中包含某些条件的其他页面像这样......
<h:panelGroup rendered="#{bean.insertMode == 'SINGLE'}">
<ui:include src="_single.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{bean.insertMode == 'DOUBLE'}">
<ui:include src="_double.xhtml" />
</h:panelGroup>
Run Code Online (Sandbox Code Playgroud)
现在在这些页面中,我有"几乎"相同的组件层次结构(复杂)具有不同的操作行为(不仅方法调用,还有视图),例如:
_single.xhtml
<p:inputText id="fieldID" value="#{bean.value}" />
<p:commandLink actionListener="#{bean.singleAction()}" />
Run Code Online (Sandbox Code Playgroud)
_double.xhtml
<p:inputText id="fieldID" value="#{bean.value}" />
<p:commandLink actionListener="#{bean.doubleAction()}" />
Run Code Online (Sandbox Code Playgroud)
我的小例子工作正常,并按照预期渲染,但我得到了
java.lang.IllegalStateException: Component ID fieldID has already been found in the view.
我知道JSF会处理整个页面,即使它们没有被包含在内,这就是我得到这个例外的原因.
任何聪明的方法来解决这个问题,而无需更改包含页面内的组件的ID(虽然它的工作原理,但异常是烦人的,似乎有些不对劲).
我也不想用一些具有不同ID的容器组件来包装每个页面,因此它们将具有不同的FULL ID,如formId:fieldID,因为母版页也指这些组件中的这些组件!
Bal*_*usC 33
发生重复组件ID错误,因为两者都包括物理上最终在JSF组件树中.这<h:panelGroup rendered="false">并不妨碍它们在JSF组件树中结束,而是阻止它们生成HTML输出.
您需要在JSF组件树中有条件地构建它们,而不是有条件地呈现它们的HTML输出.JSTL非常有用,因为它在视图构建期间运行:
<c:if test="#{bean.insertMode eq 'SINGLE'}">
<ui:include src="_single.xhtml" />
</c:if>
<c:if test="#{bean.insertMode eq 'DOUBLE'}">
<ui:include src="_double.xhtml" />
</c:if>
Run Code Online (Sandbox Code Playgroud)
如果您正在使用Mojarra,则只需确保至少使用2.1.18或更高版本,否则视图范围内的bean将表现得像请求范围的bean.
另一种方法是在src属性中使用EL条件运算符(<ui:include> 在视图构建期间,它本身也作为标记处理程序运行):
<ui:include src="_#{bean.insertMode eq 'SINGLE' ? 'single' : 'double'}.xhtml" />
Run Code Online (Sandbox Code Playgroud)
甚至insertMode直接使用文件名:
<ui:include src="_#{fn:toLowerCase(bean.insertMode)}.xhtml" />
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,您都需要确保#{bean.insertMode}在视图构建期间可用,并且在回发的恢复视图阶段期间也可以使用与初始渲染期间完全相同的值,否则视图可能会在错误的包含和JSF无法解码正确的输入和命令.此外,当您想在回发期间更改包含时,您确实需要重建视图(返回非null/ void),或发送重定向.
| 归档时间: |
|
| 查看次数: |
16688 次 |
| 最近记录: |