dng*_*fng 1 ajax composite-component jsf-2
我构建了一个复合组件,看起来像这样:
<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>
Run Code Online (Sandbox Code Playgroud)
竞争者正确显示当前标签.
<xyz:comp id="idMyComponent" label="#{someBean.text}"/>
...
<a4j:ajax ... render="idMyComponent" />
...
Run Code Online (Sandbox Code Playgroud)
现在当采取行动时,没有任何事情发生.但是,当我在组件中的ID中添加Postfix时,它可以正常工作(见下文).
...
<composite:implementation>
<h:panelGroup id="#{cc.attrs.id}Label">
...
Run Code Online (Sandbox Code Playgroud)
并使用后缀定义渲染中的ID:
<xyz:comp id="idMyComponent" label="#{someBean.text}"/>
...
<a4j:ajax ... render="idMyComponentLabel" />
...
Run Code Online (Sandbox Code Playgroud)
有些人可以向我解释为什么只有当我在ID中添加后缀时它才有效h:panelGroup
?
这个问题实际上是双重的.
第一个问题是<xyz:comp id>
实际指定了复合组件本身的ID ,即<cc:implementation>
.这默认情况下在HTML输出中没有表示,因此ajax/JavaScript无法通过document.getElementById()
和朋友找到它.
实际上,您<h:panelGroup id="#{cc.attrs.id}">
最终生成的HTML输出如下(右键单击页面和查看源以自行查看):
<span id="idMyComponent:idMyComponent">
Run Code Online (Sandbox Code Playgroud)
第二个"问题"是RichFaces/Ajax4jsf :
通过不仅在当前的上下文中搜索NamingContainer
,而且在所有其他NamingContainer
组件中搜索,通过相对客户端ID(即不是从头开始)增强了树中JSF组件的引用/查找.复合组件本质上也是一个NamingContainer
组件.
您的第一次尝试失败,因为它找到了复合本身而不是面板组,但JS/ajax反过来无法更新,因为id="myComponent"
生成的HTML输出中不存在任何HTML元素.
你的第二次尝试成功是因为它终于找到了真正的面板组(注:因为它还在所有其他搜索NamingContainer
组件,这仍然会失败,如果你使用<f:ajax>
的替代<a4j:ajax>
).
解决问题的正确方法不是#{cc.attrs.id}
在JSF组件上使用,而是#{cc.clientId}
在纯HTML元素上使用.
<span id="#{cc.clientId}">
Run Code Online (Sandbox Code Playgroud)
(是的,使用<span>
或<div>
代替<h:panelGroup>
内部<cc:implementation>
)
这样,JSF可以通过客户端ID找到组件(为了生成正确的ajax响应), JS可以通过客户端ID找到HTML元素(以便根据ajax响应更新正确的HTML元素).
归档时间: |
|
查看次数: |
2768 次 |
最近记录: |