【问题标题】:Refer to JSF dynamically generated ids based on iteration index参考JSF根据迭代索引动态生成的ids
【发布时间】:2013-04-16 17:20:24
【问题描述】:

在 JSF 中,<ui:repeat/> 和 PrimeFaces <p:dataTable/> 等类似组件根据迭代索引为子组件生成动态 id,即:

<p:dataTable id="table" var="item" value="#{itemList}">
    <h:outputText id="name" value="#{item.name}"/>
</p:dataTable>

会生成这样的东西:

<table id="table">
    <span id="table:0:name">name0</span>
    <span id="table:1:name">name1</span>
    <span id="table:2:name">name2</span>
    ...
    <span id="table:n:name">nameN</span>
</table>

所以所有元素显然都有一个不同的客户端 ID。我故意跳过了&lt;tr/&gt;&lt;td/&gt;等。

所以,&lt;p:ajax ... update=":table:name"/&gt; 引用了表中的所有名称并且它工作正常,&lt;p:ajax ... update=":table:#{someDesiredIndex}:name"/&gt; 失败并显示类似于SEVERE: javax.faces.FacesException: Cannot find component with identifier ":table:0:name" in view. 事件的消息,尽管我可以确认该组件存在于标记中。不能这样做吗?

我在 GlassFish 3.1.2 和 Mojarra 2.1.6 上运行以防万一。

【问题讨论】:

    标签: jsf-2


    【解决方案1】:

    它确实不存在于 JSF 组件树中,因为 UIViewRoot#findComponent() 可以遍历它。它仅存在于生成的 HTML 输出中。 JSF 组件树中只有一个&lt;h:outputText id="name"&gt;,而不是您预期的多个。它只是在生成 HTML 输出时被多次重用。充其量,您可以通过table:name 获取物理组件,但这又不存在于 HTML DOM 树中,因此在执行 ajax 更新期间document.getElementById() 会失败。

    无论如何,为了实现具体的功能需求,您基本上需要有一个物理存在的组件来表示 JSF 组件树中的行。如果您使用视图构建时间标记(例如 JSTL &lt;c:forEach&gt;)而不是视图呈现时间标记,则可以在循环中创建它们。

    <table id="table">
        <c:forEach items="#{itemList}" var="item" varStatus="loop">
            <tr><td><h:outputText id="table_#{loop.index}_name" value="#{item.name}" /></td></tr>
        </c:forEach>
    </table>
    

    这将在 JSF 组件树中创建物理上的多个组件,并呈现为:

    <table id="table">
        <span id="table_0_name">name0</span>
        <span id="table_1_name">name1</span>
        <span id="table_2_name">name2</span>
        ...
        <span id="table_n_name">nameN</span>
    </table>
    

    您可以通过例如引用它们update=":table_#{someDesiredIndex}_name".

    另见:


    更新:从 Mojarra 2.2.5 开始,&lt;f:ajax&gt; 不再验证客户端 ID,渲染器能够遍历迭代组件以找到要渲染的正确迭代轮次.因此,以这种方式引用 &lt;f:ajax&gt; 中的迭代索引应该可以正常工作。它只是在当前的 MyFaces 2.2.7 / PrimeFaces 5.1 版本中还不能工作,但预计他们会在未来的版本中赶上它。

    【讨论】:

    • 谢谢!我有些怀疑会是这样。如果我可以不用它,您不会推荐解决方法,对吗?然后视图可能会变得过大。
    • 我正在使用 ADF 10g (JSF 1.1),这个解决方案对我不起作用。我不知道我做错了什么,或者它是否与 JSF 1.1 有关。任何的想法?我指的是使用 id="table_#{loop.index}" 之类的表达式动态生成 id 组件
    • 感谢@BalusC!当您说旧版 JSP 时,您的意思是我使用的是旧的 JSF 实现版本,不是吗?
    • @Eduardo:从 JSF 2.0 开始,JSP 作为视图技术被 Facelets (XHTML) 弃用和取代。通过手动安装/重新配置,Facelets 也可用于 JSF 1.2,但不适用于 1.1 或更早版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多