【问题标题】:JSF same ID on rendered渲染时的 JSF 相同 ID
【发布时间】:2016-03-30 18:23:44
【问题描述】:

假设我基本上使用rendered 作为案例陈述。我有一个输入字段的标签和消息,但我希望字段本身根据情况而变化。因此:

<p:inputText id="foo" value="#{myBean.params[paramKey]}" 
   rendered="#{paramIsInput}" />
<p:calendar  id="foo" value="#{myBean.params[paramKey]}" 
   rendered="#{paramIsCalendar}" />

如果我这样做,我会收到以下错误:java.lang.IllegalStateException: Component ID j_idt64:foo has already been found in the view.

作为一种解决方法,我为每种参数类型创建了许多标签/消息并更改了它们的 ID。但这带来了我的问题。如果实际上只渲染了一个具有 id 的组件,为什么我在我的 jsf 文件中定义了多个组件呢?有没有办法让它们保持相同的 ID?

【问题讨论】:

  • 考虑paramIsInputparamIsCalendar都为真的用例......
  • 更改您的&lt;p:inputText&gt;&lt;p:calendar&gt; 的ID。即使控件没有渲染,它们也不能有相同的 id。
  • @SiB 我实际上对每个参数进行了检查,因此它们只能有 1 个 true。这不是问题
  • @DMoses 你知道......这不能用于在编写规范时做出决策:)

标签: jsf duplicates identifier illegalstateexception


【解决方案1】:

JSF 组件 ID 在视图构建期间应该是唯一的,而不是仅在视图渲染期间。这样,您实际上会得到 两个 具有相同 ID 的 JSF 组件,这确实是无效的。您希望在视图构建时间之后在 JSF 组件树中有效地以 一个 具有所需 ID 的 JSF 组件结束。

您可以通过在视图构建期间填充组件来实现此目的,而不是在视图渲染期间有条件地生成其 HTML 输出。您可以为此使用 JSTL &lt;c:if&gt; 标签。

<c:if test="#{paramIsInput}">
    <p:inputText id="foo" value="#{myBean.params[paramKey]}" />
</c:if>
<c:if test="#{paramIsCalendar}">
    <p:calendar id="foo" value="#{myBean.params[paramKey]}" />
</c:if>

这有一些警告:&lt;c:if test&gt; 条件不能依赖于仅在 JSF 渲染期间才知道的变量。所以它不必依赖于 JSF 迭代组件的var,或者是视图范围 bean 的属性等。

另见:

【讨论】:

  • 很好的信息,但条件是在视图范围的 bean 上,因为我有一个更改输入字段的选择侦听器。
  • 那么你必须让条件依赖于请求参数而不是视图范围的 bean 属性。例如。 &lt;c:if test="#{param['formId:menuId'] == 'someValue'}"&gt; 只会在 &lt;h:form id="formId"&gt;&lt;h:selectOneMenu id="menuId"&gt; 使用选项值“someValue”提交时评估为真。
  • 再次感谢您提供的信息,我阅读了 JSF2 中的 JSTL。我的整个问题都在一个中继器中,所以这使得 jstl 解决方案不可行,但我从你的回答中学到了很多。
【解决方案2】:

如果实际上只渲染了一个具有 id 的组件,为什么我在我的 jsf 文件中定义了多个呢?

JSF 怎么知道只有一个组件会被渲染?您在rendered 中使用EL,两者都可以评估为真。这是documentation,它表示命名容器中不能有重复的 ID。

指定的标识符在所有组件(包括构面)中必须是唯一的,这些组件是作为 NamingContainer 的最近祖先 UIComponent 的后代,或者在整个组件树的范围内(如果没有这样的祖先是 NamingContainer)。

-

有没有办法让它们保持相同的 ID?

如果您仍想在多个组件上使用相同的 ID,则需要分隔命名容器。

您可以使用PanelGrid 作为命名容器。

【讨论】:

  • 谢谢。我想我希望的是一个真正的 switch 语句,它会被识别为这样,所以 JSF 知道它们不能重复。命名容器是有道理的,但是因为我希望消息和标签在同一个 id 上匹配,所以这是行不通的。我想我会保留我拥有的多个标签/消息和不同的 ID。
  • PanelGrid 不是命名容器
猜你喜欢
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-26
  • 2011-09-09
  • 2012-11-28
  • 2012-04-01
相关资源
最近更新 更多