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

时间:2013-03-27 14:09:21

标签: jsf jsf-2 datatable

我有一个数据表,我想在构建表的数组中将每行的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?

2 个答案:

答案 0 :(得分:23)

从JSF UI组件中,在视图构建时,即要解析XHTML / JSP文件中的XML树结构并将其转换为a时,将评估idbinding属性。 FacesContext#getViewRoot()提供的JSF组件树。但是,<h:dataTable>在视图呈现时间内进行迭代,即JSF组件树需要按UIViewRoot#encodeAll()生成HTML代码的时刻。因此,在那一刻,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}" ... />
    

    另见JSTL in JSF2 Facelets... makes sense?

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

    <span id="#{item.id}">
    

    请注意,根据invalid,以HTML开头的ID为HTML spec chapter 6.2。您可能希望在其前面添加一些字符串,如下所示:

    <span id="item_#{item.id}">
    
  3. 请勿使用动态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时它是空的。