我有一个数据表,我想在构建表的数组中将每行的id设置为当前项(具有id字段的对象)的id。
示例:
<h:dataTable
value="#{bean.list}"
var="item">
<h:column>
<h:outputText id="#{item.id}" .... />
</h:column>
</h:dataTable>
这不起作用:javax.servlet.ServletException: Empty id attribute is not allowed
。
由于JSF如何构建其id,或者我做错了什么,是不可能以这种方式设置id?
答案 0 :(得分:23)
从JSF UI组件中,在视图构建时,即要解析XHTML / JSP文件中的XML树结构并将其转换为a时,将评估id
和binding
属性。 FacesContext#getViewRoot()
提供的JSF组件树。但是,<h:dataTable>
在视图呈现时间内进行迭代,即JSF组件树需要按UIViewRoot#encodeAll()
生成HTML代码的时刻。因此,在那一刻,id
属性被评估,#{item}
在EL范围内无处可用,并且评估为null
,最终打印出一个空字符串。
基本上有3个解决方案:
使用像JSTL <c:forEach>
这样的视图构建时标记,以便在视图构建时也可以使用#{item}
。
<table>
<c:forEach items="#{bean.list}" var="item">
<tr><td><h:outputText id="#{item.id}" ... />
不要将其打印为JSF组件的ID,而是打印为纯HTML元素。
<span id="#{item.id}">
请注意,根据invalid,以HTML开头的ID为HTML spec chapter 6.2。您可能希望在其前面添加一些字符串,如下所示:
<span id="item_#{item.id}">
请勿使用动态ID。只需使用固定ID。无论如何,JSF将基于行索引自动生成唯一ID。
<h:outputText id="foo" ... />
如果它位于<span id="formId:tableId:0:foo">
内,最终会像<h:form id="formId"><h:dataTable id="tableId">
一样。 0
是基于0的行索引,每行递增一次。因此,这保证了每行中的唯一ID,而无需自己担心。
答案 1 :(得分:2)
您不能以这种方式在id
属性中使用EL。 id
属性在视图构建期间应该可用,但在视图渲染时评估EL。这太晚了,所以在检查id
时它是空的。