假设我使用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?
答案 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作为命名容器。