将 JSF dataTable 中组件的 id 设置为数组中当前项的值
Posted
技术标签:
【中文标题】将 JSF dataTable 中组件的 id 设置为数组中当前项的值【英文标题】:Set id of a component within JSF dataTable to value from current item in the array 【发布时间】:2013-03-17 15:49:10 【问题描述】:我有一个数据表,我想将每一行的 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,还是我做错了什么?
【问题讨论】:
最好设置value
而不是id,但问题的性质表明您的功能要求是编辑/删除一行中的数据。如果这是正确的,那么您将采用错误的方法。
这个想法是有一种简单的方法来引用每行,其中 id 也连接到(引用)数据库中对象的实际 id。
【参考方案1】:
从 JSF UI 组件中,id
和 binding
属性在视图构建时进行评估,此时 Xhtml/JSP 文件中的 XML 树结构将被解析并转换为 JSF 组件树由FacesContext#getViewRoot()
提供。但是,<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" ... />
另请参阅JSTL in JSF2 Facelets... makes sense?
不要将其打印为 JSF 组件的 ID,而是作为普通 HTML 元素的 ID。
<span id="#item.id">
请注意,根据HTML spec chapter 6.2,在 HTML 中以数字开头的 ID 是 invalid。你可能想在它前面加上一些像这样的字符串:
<span id="item_#item.id">
不要使用动态 ID。只需使用固定 ID。无论如何,JSF 都会根据行索引自动生成唯一 ID。
<h:outputText id="foo" ... />
如果它位于 <h:form id="formId"><h:dataTable id="tableId">
内,则它最终会像 <span id="formId:tableId:0:foo">
一样。 0
是基于 0 的行索引,每行递增。因此,这保证了每一行中的唯一 ID,而无需自己担心。
【讨论】:
谢谢。当我回复 Luiggi 时,我想参考数据库中对象的实际 ID。这是为了从“外部”参考点轻松滚动到行。现在可能有一百万种不同的方法来实现这一点,但我认为从数据库中获取实际的 id 将是一种简单的方法。我相信您提出的解决方案 2 可以正常工作。再来一次;谢谢!【参考方案2】:您不能以这种方式在id
属性中使用EL。 id
属性应该在视图构建期间可用,但您的 EL 在视图渲染期间进行评估。为时已晚,所以在检查id
时它是空的。
【讨论】:
以上是关于将 JSF dataTable 中组件的 id 设置为数组中当前项的值的主要内容,如果未能解决你的问题,请参考以下文章
通过 Ajax 更新 JSF 组件后,JavaScript/jQuery 事件侦听器不起作用