gpt4 book ai didi

JSF 有条件包含,因为组件 ID 已在 View 中找到

转载 作者:行者123 更新时间:2023-12-02 05:08:01 25 4
gpt4 key购买 nike

我知道我们不能重复同一 View 树中的任何组件的 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>

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

_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()}" />

我的小例子工作正常,并且按预期渲染,但我得到了

java.lang.IllegalStateException:组件 ID fieldID 已在 View 中找到。

我知道 JSF 会处理完整的页面,即使它们不包含在内,这就是我收到此异常的原因。

任何聪明的方法都可以在不更改包含页面内组件的 ID 的情况下解决此问题(虽然它有效,但异常很烦人并且似乎出了问题)。

我不想用某个具有不同 ID 的容器组件来包装每个页面,这样它们就会有一个不同的完整 ID,如 formId:fieldID,因为母版页也引用这些组件其中包括!

最佳答案

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

您需要有条件地在 JSF 组件树中构建它们,而不是有条件地呈现它们的 HTML 输出。 JSTL 在这方面非常有帮助,因为它在 View 构建期间运行:

<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 或更高版本,否则 View 作用域 bean 的行为将类似于请求作用域 bean。

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

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

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

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

无论哪种方式,您都需要绝对确保 #{bean.insertMode}在 View 构建时可用,并且在回发的恢复 View 阶段与初始渲染期间可用完全相同的值,否则 View 可能会使用错误的包含来恢复,并且 JSF 无法解码正确的输入并不再指挥。另外,当您想在回发期间更改包含内容时,您确实需要重建 View (返回非 null/void ),或发送重定向。

另请参阅:

关于JSF 有条件包含,因为组件 ID 已在 View 中找到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18768527/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com