参考JSF基于迭代索引动态生成的id [英] Refer to JSF dynamically generated ids based on iteration index

查看:16
本文介绍了参考JSF基于迭代索引动态生成的id的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In JSF, <ui:repeat/> and similar components such as PrimeFaces <p:dataTable/> generate dynamic ids for sub-components based on the iteration index, i.e.:

<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.我故意跳过了

so all the elements clearly have a distinct client id. I intentionally skipped the <tr/>, <td/>, etc.

所以,<p:ajax ... update=":table:name"/> 指的是表中的所有名称,它工作正常,<p:ajax ... update=":table:#{someDesiredIndex}:name"/> 失败并显示类似于 SEVERE: javax.faces.FacesException: 无法找到具有标识符:table 的组件"的消息:0:name" 在视图中. 事件虽然我可以确认该组件存在于标记中.这是不可能的吗?

So, <p:ajax ... update=":table:name"/> refers to all the names in the table and it works fine, <p:ajax ... update=":table:#{someDesiredIndex}:name"/> fails with a message similar to SEVERE: javax.faces.FacesException: Cannot find component with identifier ":table:0:name" in view. event though I can confirm that the component exists in the markup. Is it not possible to do this?

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

I'm running on GlassFish 3.1.2 and Mojarra 2.1.6 in case it is relevant.

推荐答案

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

It does indeed not exist in the JSF component tree as traversable by UIViewRoot#findComponent(). It exists only in the generated HTML output. There's only one <h:outputText id="name"> in the JSF component tree, not multiple as you seemed to expect. It's just been reused multiple times when producing the HTML output. At best, you can get the physical component by table:name, but this does in turn not exist in the HTML DOM tree, so the document.getElementById() would fail on that during performing the ajax update.

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

In order to achieve the concrete functional requirement anyway, you basically need to have a physical existing component representing the row in the JSF component tree. You can create them in a loop if you use a view build time tag, such as JSTL <c:forEach>, instead of a view render time tag.

<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 组件树中创建物理上的多个组件,并呈现为:

This will create physically multiple components in the JSF component tree and this get rendered as:

<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".

And you can reference them via e.g. update=":table_#{someDesiredIndex}_name".

更新:自 Mojarra 2.2.5 起,<f:ajax> 不再验证客户端 ID,渲染器能够遍历迭代组件为了找到正确的迭代回合进行渲染.因此,以这种方式在 中引用迭代索引应该可以正常工作.它仅在当前的 MyFaces 2.2.7/PrimeFaces 5.1 版本中尚不可用,但预计它们会在未来版本中赶上.

Update: since Mojarra 2.2.5, the <f:ajax> doesn't validate the client ID anymore and the renderer is capable of walking through iterating components in order to find the right iteration round to render. So referencing the iteration index in <f:ajax> this way should just work fine. It only doesn't work yet in current MyFaces 2.2.7 / PrimeFaces 5.1 versions, but it's expected that they will catch up it in a future version.

这篇关于参考JSF基于迭代索引动态生成的id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆