JSF条件包含,因为已在视图中找到组件ID [英] JSF Conditional includes, cause Component ID has already been found in the view

查看:249
本文介绍了JSF条件包含,因为已在视图中找到组件ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我们无法重复在同一视图树中拥有的任何组件的ID.

I know we can't repeat the ID of any component we have in the same view tree.

我有一个页面,其中包含某些条件的其他页面,像这样...

I have a page which includes another pages by certain condition Like this...

<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>

现在,在这些页面中,我具有几乎"相同的组件层次结构(复杂),具有不同的动作行为(不仅是方法调用,还包括视图),例如:

Now In these pages I have "Almost" the same components hierarchy (Complex) with different actions behaviour (Not only method calls, also view), for example:

_single.xhtml

<p:inputText id="fieldID" value="#{bean.value}" />
<p:commandLink actionListener="#{bean.singleAction()}" />

_double.xhtml

<p:inputText id="fieldID" value="#{bean.value}" />
<p:commandLink actionListener="#{bean.doubleAction()}" />

我的小例子可以正常工作,并按预期方式进行渲染,但是我明白了

My little example works fine, and renders as it supposed to, but I get

java.lang.IllegalStateException: Component ID fieldID has already been found in the view.

我知道即使没有包含完整页面,JSF也会处理整个页面,这就是为什么我遇到此异常.

I know that JSF process the full pages even if they are not included and that's why I'm getting this exception.

在不更改包含页面内组件ID的情况下,任何解决此问题的明智方法(尽管它可以工作,但异常令人讨厌,并且似乎出了点问题).

Any smart way to solve this without changing the IDs of the components inside the include pages (Although it works, but the exception is annoying and seems something is wrong).

我也不想用具有不同ID的某些容器组件来包装每个页面,因此它们将具有不同的FULL ID(例如formId:fieldID),因为母版页也引用了这些组件其中包括!

I don't want also to wrap each one of the pages with some container component with a different ID so they would have a different FULL ID like formId:fieldID because the master page is also referring to these components inside these includes!

推荐答案

发生重复的组件ID错误,因为两者实际上都包含在JSF组件树中. <h:panelGroup rendered="false">不会阻止它们最终出现在JSF组件树中,而是阻止它们生成HTML输出.

The duplicate component ID error occurs because the both includes physically end up in the JSF component tree. The <h:panelGroup rendered="false"> doesn't prevent them from ending up in JSF component tree, instead it prevents them from generating their HTML output.

您需要在JSF组件树中有条件地构建它们,而不是有条件地呈现它们的HTML输出. JSTL在视图构建期间运行,对此非常有帮助:

Instead of conditionally rendering their HTML output, you need to conditionally build them in the JSF component tree. JSTL is very helpful in this as it runs during view build time:

<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>

如果您使用的是Mojarra,则只需确保至少使用2.1.18版或更高版本,否则查看作用域的bean的行为将类似于请求作用域的bean.

In case you're using Mojarra, you only need to make sure you use at least version 2.1.18 or newer, otherwise view scoped beans will behave like request scoped beans.

一种替代方法是在src属性中使用EL条件运算符(<ui:include>本身在视图构建期间也作为标记处理程序运行):

An alternative is to make use of EL conditional operator in src attribute (the <ui:include> itself runs as being a taghandler also during view build time):

<ui:include src="_#{bean.insertMode eq 'SINGLE' ? 'single' : 'double'}.xhtml" />

或者甚至直接将insertMode用作文件名:

Or even use the insertMode directly as filename:

<ui:include src="_#{fn:toLowerCase(bean.insertMode)}.xhtml" />

无论哪种方式,您都需要确保#{bean.insertMode}在视图构建期间可用,并且必须确保回发的还原视图阶段与初始渲染期间完全相同的值可用,否则,视图可能会使用错误的include进行恢复,并且JSF无法再解码正确的输入和命令.另外,当您想在回发期间更改包含时,确实需要重建视图(返回非null/void)或发送重定向.

Either way, you need to make absolutely sure that the #{bean.insertMode} is available during view build time, and also that exactly the same value is available during the restore view phase of postbacks as it was during initial render, otherwise the view would possibly be restored with the wrong include and JSF can't decode the right inputs and command anymore. Also, when you want to change the include during postback, you really need to rebuild the view (return non-null/void), or to send a redirect.

这篇关于JSF条件包含,因为已在视图中找到组件ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆