14

各行の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を設定することはできませんか、それとも私は何か間違ったことをしていますか?

4

2 に答える 2

23

JSF UIコンポーネントから、idおよびbinding属性は、ビューのビルド時に評価されます。これは、XHTML / JSPファイルのXMLツリー構造が解析され、によって使用可能なJSFコンポーネントツリーに変換される瞬間です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}" ... />
    

    JSF2 FaceletsのJSTLも参照してください...意味がありますか?

  2. JSFコンポーネントのIDとしてではなく、プレーンなHTML要素のIDとして出力します。

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

    HTML仕様の第6.2章にあるように、数字で始まるIDはHTMLでは無効であることに注意してください。次のような文字列をプレフィックスとして付けることができます。

    <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が保証されます。

于 2013-03-27T14:18:17.307 に答える
2

idこの方法で属性にELを使用することはできません。id属性はビューのビルド時に使用可能である必要がありますが、ELはビューのレンダリング時に評価されます。これは遅すぎるので、idチェックするとすぐに空になります。

于 2013-03-27T14:14:35.447 に答える