将JSF dataTable中组件的id设置为数组中当前项的值

niv*_*vis 14 datatable jsf jsf-2

我有一个数据表,我想在构建表的数组中将每行的id设置为当前项(具有id字段的对象)的id.

例:

<h:dataTable
   value="#{bean.list}"
   var="item">
      <h:column>
         <h:outputText id="#{item.id}" .... />
      </h:column>
</h:dataTable>
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为我得到:javax.servlet.ServletException: Empty id attribute is not allowed.

由于JSF如何构建其id,或者我做错了什么,是不可能以这种方式设置id?

Bal*_*usC 23

在JSF UI组件中,在视图构建时,即要解析XHTML/JSP文件中的XML树结构并将其转换为可用的JSF组件树时,将评估idbinding属性FacesContext#getViewRoot().但是,<h:dataTable>在视图渲染时间内,JSF组件树需要生成HTML代码的时刻进行迭代UIViewRoot#encodeAll().因此,在此时id评估属性,#{item}EL范围中无处可用,并评估null最终打印空字符串.

基本上有3种解决方案:

  1. 使用像JSTL <c:forEach>这样的视图构建时标记,以便#{item}在视图构建时也可以使用它.

    <table>
        <c:forEach items="#{bean.list}" var="item">
            <tr><td><h:outputText id="#{item.id}" ... />
    
    Run Code Online (Sandbox Code Playgroud)

    另请参阅JSF2 Facelets中的JSTL ......有意义吗?

  2. 不要将其打印为JSF组件的ID,而是打印为纯HTML元素.

    <span id="#{item.id}">
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,根据HTML规范6.2章,HTML中以数字开头的ID 无效.您可能希望在其前面添加一些字符串,如下所示:

    <span id="item_#{item.id}">
    
    Run Code Online (Sandbox Code Playgroud)
  3. 不要使用动态ID.只需使用固定ID.无论如何,JSF将基于行索引自动生成唯一ID.

    <h:outputText id="foo" ... />
    
    Run Code Online (Sandbox Code Playgroud)

    这将最终<span id="formId:tableId:0:foo">提供,就像它在里面一样<h:form id="formId"><h:dataTable id="tableId">.该0是递增每一行的从零开始的行索引.因此,这保证了每行中的唯一ID,而无需自己担心.