我已经构建了一个复合组件,看起来像这样:
<composite:interface>
<composite:attribute name="id" required="false" />
<composite:attribute name="label" required="true" />
</composite:interface>
<composite:implementation>
<h:panelGroup id="#{cc.attrs.id}">
<fieldset class="fieldset"><legend>${cc.attrs.label}</legend></fieldset>
</h:panelGroup>
</composite:implementation>
竞争者正确显示当前标签。
<xyz:comp id="idMyComponent" label="#{someBean.text}"/>
...
<a4j:ajax ... render="idMyComponent" />
...
现在当采取行动时,没有任何事情发生。但是,当我在组件中的ID中添加Postfix时,它工作正常(见下文)。
...
<composite:implementation>
<h:panelGroup id="#{cc.attrs.id}Label">
...
使用后缀定义渲染中的ID:
<xyz:comp id="idMyComponent" label="#{someBean.text}"/>
...
<a4j:ajax ... render="idMyComponentLabel" />
...
有些人可以向我解释为什么只有当我在h:panelGroup
的ID中添加后缀时它才有用吗?
答案 0 :(得分:5)
这个问题实际上是双重的。
第一个问题是<xyz:comp id>
实际上指定了复合组件本身的ID ,<cc:implementation>
。默认情况下,这在HTML输出中没有表示,因此document.getElementById()
和朋友无法找到ajax / JavaScript。
实际上,您的<h:panelGroup id="#{cc.attrs.id}">
最终生成的HTML输出如下(右键单击页面和查看源以自行查看):
<span id="idMyComponent:idMyComponent">
第二个“问题”是RichFaces / Ajax4jsf通过相关客户端ID(即不以:
开头)增强了树中JSF组件的引用/查找,不仅仅是在当前的上下文中搜索NamingContainer
,以及所有其他NamingContainer
组件。复合组件本质上也是NamingContainer
组件。
您的第一次尝试失败,因为它找到了复合本身而不是面板组,但JS / ajax反过来无法更新,因为在生成的HTML输出中不存在任何带有id="myComponent"
的HTML元素。
您的第二次尝试成功,因为它最终找到了真正的小组(请注意:因为它还搜索了所有其他NamingContainer
个组件;如果您使用<f:ajax>
而不是{{},那么这仍然会失败{1}})。
解决问题的正确方法是在JSF组件上使用<a4j:ajax>
,而在纯HTML元素上使用#{cc.attrs.id}
。
#{cc.clientId}
(是的,在<span id="#{cc.clientId}">
内使用<span>
或<div>
代替<h:panelGroup>
这样JSF可以通过客户端ID找到组件(为了生成正确的ajax响应)和 JS可以通过客户端ID找到HTML元素(为了更新正确的HTML元素关于ajax回应)。