通过ajax重新渲染复合组件 [英] Rerendering composite component by ajax

查看:24
本文介绍了通过ajax重新渲染复合组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<composite:attribute name="id" required="false"/><composite:attribute name="label" required="true"/></composite:interface><复合:实现><h:panelGroup id="#{cc.attrs.id}"><fieldset class="fieldset"><legend>${cc.attrs.label}</legend></fieldset></h:panelGroup></composite:implementation>

该组件正确显示当前标签.

...<a4j:ajax ... render="idMyComponent"/>...

现在当动作被执行时,什么都不会发生.但是,当我向组件中的 ID 添加 Postfix 时,它工作正常(见下文).

<代码>...<复合:实现><h:panelGroup id="#{cc.attrs.id}Label">...

并用后缀定义渲染中的ID:

...<a4j:ajax ... render="idMyComponentLabel"/>...

有人可以向我解释为什么它只在我向 h:panelGroup 中的 ID 添加后缀时才有效吗?

解决方案

这个问题其实有两个方面.

第一个问题是实际上指定了复合组件本身的ID,.默认情况下,这在 HTML 输出中没有任何表示,因此 ajax/JavaScript 无法通过 document.getElementById() 和朋友找到它.

实际上,您的 <h:panelGroup id="#{cc.attrs.id}"> 最终生成的 HTML 输出如下(右键单击页面和 View来源自己看):

第二个问题"是 RichFaces/Ajax4jsf 通过不仅在当前 NamingContainer<的上下文中搜索,增强了通过相对客户端 ID(即不以 : 开头)树中 JSF 组件的引用/查找/code>,但也适用于所有其他 NamingContainer 组件.复合组件本质上也是一个 NamingContainer 组件.

您的第一次尝试失败了,因为它找到了组合本身而不是面板组,但是 JS/ajax 又未能更新,因为不存在任何带有 id="myComponent" 在生成的 HTML 输出中.

您的第二次尝试成功了,因为它终于找到了真正的面板组(注意:因为它还搜索了所有其他 NamingContainer 组件;如果您使用了 < 这仍然会失败;f:ajax> 而不是 ).

解决问题的正确方法不是在 JSF 组件上使用 #{cc.attrs.id},而是在 JSF 组件上使用 #{cc.clientId}纯 HTML 元素.

(是的,在内部使用

而不是 )

这种方式 JSF 可以通过客户端 ID 找到组件(为了生成正确的 ajax 响应) JS 可以通过客户端 ID 找到 HTML 元素(为了更新正确的 HTML 元素基于关于 ajax 响应).

另见:

I have build a composite component witch looks something like this:

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

The compent displays the current label correctly.

<xyz:comp id="idMyComponent" label="#{someBean.text}"/>

...
<a4j:ajax ... render="idMyComponent" />
...

Now when the action is preformed nothing happens. However when I add a Postfix to the ID in the component it works fine (see below).

...
<composite:implementation>
      <h:panelGroup id="#{cc.attrs.id}Label">
...

And define the ID in render with the postfix:

<xyz:comp id="idMyComponent" label="#{someBean.text}"/>

...
<a4j:ajax ... render="idMyComponentLabel" />
...

Can some on explain to me why it only works when I add a postfix to the ID in h:panelGroup?

解决方案

This problem is actually two-fold.

The first problem is that the <xyz:comp id> actually specifies the ID of the composite component itself, the <cc:implementation>. This is by default nowhere represented in HTML output and therefore ajax/JavaScript can't locate it by document.getElementById() and friends.

Actually, your <h:panelGroup id="#{cc.attrs.id}"> ends up in generated HTML output as follows (rightclick page and View Source to see it yourself):

<span id="idMyComponent:idMyComponent">

The second "problem" is that RichFaces/Ajax4jsf has enhanced the referencing/finding of JSF components in the tree by relative client ID (i.e. not starting with :) by not only searching in the context of the current NamingContainer, but also in all other NamingContainer components. A composite component is inherently also a NamingContainer component.

Your first attempt failed because it found the composite itself instead of the panel group, but JS/ajax in turn failed to update because there doesn't exist any HTML element with id="myComponent" in the generated HTML output.

Your second attempt succeeded because it finally found the real panel group (note: because it also searched in all other NamingContainer components; this would still have failed if you've used <f:ajax> instead of <a4j:ajax>).

The right way to fix your problem is not using #{cc.attrs.id} on a JSF component, but using #{cc.clientId} on a plain HTML element.

<span id="#{cc.clientId}">

(yes, use a <span> or <div> instead of <h:panelGroup> inside the <cc:implementation>)

This way JSF can find the component by client ID (in order to generate the proper ajax response) and JS can find the HTML element by client ID (in order to update the right HTML element based on ajax response).

See also:

这篇关于通过ajax重新渲染复合组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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