我有以下代码:
<ui:repeat var="class2" value="#{bean.list}" varStatus="status">
<h:form id="#{class2.name}">
<h:outputText value="#{class2.name}" />
</h:form>
</ui:repeat>
但是,当我打开页面时,它的错误如下:
组件标识符不能是零长度字符串
但它已在<h:outputText>
中正确打印。这是怎么造成的,我该如何解决?
答案 0 :(得分:25)
您可以在JSF组件的id
属性中使用EL,但EL变量必须在视图构建时期间可用,而要构建JSF组件树。但是,<ui:repeat>
在视图渲染时间期间运行,而HTML输出将基于JSF组件树生成。 <ui:repeat var>
在视图构建期间不可用,#{class2.name}
评估为null
,这完全解释了您获得的错误。它在<h:outputText>
中有效是因为它在视图渲染时运行。
如果您将<ui:repeat>
替换为<c:forEach>
,它在视图构建期间运行,那么它将按您的意图运行。 <c:forEach>
将在JSF组件树中生成物理上多个<h:form>
组件,每个组件都单独生成自己的HTML输出(与<ui:repeat>
相反,其中<h:form>
组件相同已多次重复使用以生成HTML输出。)
<c:forEach var="class2" items="#{bean.list}" varStatus="status">
<h:form id="#{class2.name}">
<h:outputText value="#{class2.name}" />
</h:form>
</c:forEach>
但是,我真的很想知道为什么你需要这样做。通常无需动态分配组件ID。 JSF已经确保了ID的唯一性。下面的例子,
<ui:repeat var="class2" value="#{bean.list}" varStatus="status">
<h:form id="form">
<h:outputText value="#{class2.name}" />
</h:form>
</ui:repeat>
将以多种形式结束,每个形式都有一个唯一的ID,后缀为<ui:repeat>
的迭代索引。如果你真的需要使用#{class2.name}
来实现一些JavaScript / jQuery(你没有说明问题的具体功能要求,你认为这是正确的解决方案,所以它只是猜测),然后只是换行它在一个简单的vanilla HTML元素中:
<ui:repeat var="class2" value="#{bean.list}" varStatus="status">
<div id="#{class2.name}">
<h:form id="form">
<h:outputText value="#{class2.name}" />
</h:form>
</div>
</ui:repeat>
或者将其设置为JSF组件的样式类,也可以通过CSS选择器选择:
<ui:repeat var="class2" value="#{bean.list}" varStatus="status">
<h:form id="form" styleClass="#{class2.name}">
<h:outputText value="#{class2.name}" />
</h:form>
</ui:repeat>