我需要为JSF中的某些组件生成动态ID来解决我的问题。
看一下这个例子:
<h:outputText id="#{bean.id}" value="#{bean.value}" />
我的问题是我收到了这个错误:
java.lang.IllegalArgumentException: Empty id attribute is not allowed
当我查看生成的HTML输出时,组件的ID为空。这是怎么造成的,我该如何解决?
答案 0 :(得分:18)
你是对的。我在数据表中使用它。
如果#{bean}
表示var
属性中声明的当前迭代对象,则会发生这种情况,如下所示:
<h:dataTable value="#{someBean.beans}" var="bean">
<h:column>
<h:outputText id="#{bean.id}" value="#{bean.value}" />
JSF组件的id
(和binding
)属性在视图构建期间进行评估,即需要组合JSF组件树的那一刻。但是,#{bean}
仅在视图渲染时可用,即<h:dataTable>
需要遍历所有对象并为每个对象生成HTML表行的那一刻。因此#{bean}
在视图构建期间不可用,并且评估为null
,最终将EL强制转换为空字符串。因此异常java.lang.IllegalArgumentException: Empty id attribute is not allowed
。
你基本上有3种选择:
使用视图构建时标记来迭代集合。您只需要自己编写所有HTML样板:
<table>
<c:forEach items="#{someBean.beans}" var="bean">
<tr>
<td>
<h:outputText id="#{bean.id}" value="#{bean.value}" />
使用纯HTML元素:
<h:dataTable value="#{someBean.beans}" var="bean">
<h:column>
<span id="#{bean.id}">#{bean.value}</span>
不要设置动态ID,而是设置固定ID。 JSF将通过在表格的行索引前面添加它来确保HTML输出的唯一性:
<h:dataTable value="#{someBean.beans}" var="bean">
<h:column>
<h:outputText id="id" value="#{bean.value}" />