通过ajax重新渲染复合组件

时间:2013-08-22 11:53:49

标签: ajax jsf-2 composite-component

我已经构建了一个复合组件,看起来像这样:

<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中添加后缀时它才有用吗?

1 个答案:

答案 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回应)。

另见: