JSF渲染时的ID相同

时间:2012-08-28 17:11:28

标签: jsf duplicates identifier illegalstateexception

假设我使用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?

2 个答案:

答案 0 :(得分:7)

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

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

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

然而,这有一些警告:<c:if test>条件不能依赖于仅在JSF渲染时间内已知的变量。所以它不依赖于JSF迭代组件的var,或者是视图范围bean的属性等。

另见:

答案 1 :(得分:4)

  

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

JSF如何知道只会呈现一个组件?您在EL中使用rendered,两者都可以评估为true。这是documentation,表示您不能在命名容器中包含重复的ID。

  

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

-

  

有没有办法让他们拥有所有相同的ID?

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

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