2

我有以下结构(省略内容和属性):

<ui:repeat id="outerlist">
    <my:compositeComponent id="myCC">
        <h:panelgroup id="container">
            Some content here (outputText, etc.)
            <ui:repeat id="innerlist">
               <h:commandButton>
                   <f:ajax render=":#{cc.clientId}:container" />

<!-- all closing tags accordingly -->

由于容器内的内容取决于内部列表按钮的操作,因此我需要对其进行更新。当没有 external 时,上面显示的方法有效ui:repeat。但是,component not found当有一个错误时,它会失败并出现错误。

这似乎是由于cc.clientIdthen 本身包含外部的行索引ui:repeat,例如outerlist:0:myCC:container。正如对此答案的评论所示,此索引 ID 在视图树的服务器端表示中不可用。而是“行索引仅存在于客户端”。我必须承认我不太了解这个索引是如何完成的,以及服务器端有什么可用的。

所以我的问题是:JSF 如何做这个索引,它(在服务器上)如何在 a 中分离不同的“实例”,ui:repeat并且有没有解决我想要用上面的代码实现的解决方案?

4

3 回答 3

3

中指定的客户端 ID<f:ajax>必须在JSF 的服务器端都可用

facesContext.getViewRoot().findComponent(clientId);

(以便可以找到它以便为 ajax 响应呈现其新的 HTML 表示)

在客户端由 JavaScript 的

document.getElementById(clientId);

(这样一旦带有新 HTML 内容的 ajax 响应到达,它就可以由 JS 更新/替换)

由于<ui:repeat>仅在视图渲染期间运行,具有行索引的客户端 ID 不代表服务器端的有效组件(来自 的“找不到组件...”错误findComponent()),但它确实代表客户端的有效 HTML 元素. 基本上,您需要没有服务器端行索引的客户端 ID 和客户端有行索引的客户端 ID。但这只是行不通的,<ui:repeat>因为它(不幸地)不可能通过单独选择特定迭代的组件树状态findComponent()

当使用 JSTL<c:forEach>并在视图构建期间运行时动态分配组件 ID 时,它应该可以正常工作,并且实际上还会在视图树中生成多个完全值得的 JSF 组件,而不是仅在渲染期间重复使用一个多次。

<c:forEach varStatus="loop">
    <my:compositeComponent id="myCC">
        <h:panelGroup id="container_#{loop.index}">
            Some content here (outputText, etc.)
            <ui:repeat id="innerlist_#{loop.index}">
               <h:commandButton>
                   <f:ajax render=":#{cc.clientId}:container_#{loop.index}" />

然而,这有其自身的含义,尤其是在与复合组件一起使用时以及在嵌套循环中使用时。您的代码不够完整,无法就此提供见解和建议。例如,当这段代码被放置在一个复合组件中时,它会中断,该组件本身也在渲染时间循环中被多次重用。

也可以看看:

于 2012-11-19T17:05:38.683 回答
0

作为更新:在这种特殊情况下, usingc:foreach不是一个选项,因为两个列表都需要是动态的(尽管这条路线在其他一些情况下为我节省了很多麻烦)相反,我向复合组件添加了一个属性以传递一个可选“更新范围”像这样:

<cc:attribute name="updateScope" required="false" type="java.lang.String"  
              default=":#{cc.clientId}:container" />

通过设置默认值,我不需要在非循环上下文中更改组件的任何使用。但是,如果我想在 a 中使用它,ui:repeat我可以将一个 ID 传递给足够宽以包含外循环的属性。通常,这将h:panelGroup id="wrapper"ui:repeat.

显然,这有一些缺点:它会更新循环的所有孩子,这可能会导致大量不必要的内容被重新渲染。这样做的一个令人讨厌的副作用是这些同级的错误消息和本地值被重置。在我们的一个页面中,它还导致所有展开的面板重置为关闭状态。

但是,如果这些问题不重要(例如:我的原始示例引用了一个没有输入字段或面板,但只有反馈文本和操作的组件),则附加属性可以是解决所描述的问题的简单方法问题。

于 2013-04-12T11:23:20.807 回答
0

我只是像这样自己解决了这个问题:

update=":#{cc.clientId.replaceAll(':[0-9]+:', ':')}"
于 2014-06-01T12:48:13.240 回答