附加到Composite Component更新模型的Ajax但不会触发侦听器

时间:2012-09-17 11:26:27

标签: jsf-2 composite-component

我有自定义组件location。我想要的是,当完成更改时,模型会更新,因此另一个组件(自动完成)只显示与location值相关的结果。此外,该组件将被重新呈现以重置它。

我有一个包含以下代码的页面(简化):

<h:form id="ticketForm">
  ...
  <loc:location id="locationId"                         <-- CUSTOM COMPONENT
    hiddenFieldValue="#{ticketCtrl.ticket.location}"
    visibleFieldValue="#{ticketCtrl.ticket.locationDescription}"
    rendered="#{ticketCtrl.ticketModifiable}">

    <f:ajax event="changeLocation" render=":ticketForm:gfhId"       <-- AJAX CALL.
      execute=":ticketForm:locationId" listener="#{ticketCtrl.locationListener}"/>
  </loc:location>
  ...
</h:form>

当更改组件中的值时,将更新模型并根据需要呈现:ticketForm:gfhId,但不会执行侦听器(执行其他重置)。

将ajax附加到更简单的控件会导致侦听器被执行; v.g。

<h:inputText id="contactId"
  value="#{ticketCtrl.ticket.contactPerson}"
  disabled="#{not ticketCtrl.ticketModifiable}">
  <f:ajax event="change" render=":ticketForm:gfhId"
    execute=":ticketForm:locationId" listener="#{ticketCtrl.locationListener}"/>
</h:inputText>

完美无缺。

我不知道它是否与changeLocation事件的触发方式有关;在我的组件中,我将其定义为

<composite:interface>
   ...
   <composite:clientBehavior name="changeLocation" event="change" targets="visibleId"/>
</composite:interface>

visibleId是只读文字;当它被javascript更改时,我用JS激活change事件。

function launchEvent(fieldName) {
  if ("fireEvent" in fieldName) {
    fieldName.fireEvent("onchange");
  } else {
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent("change", false, true);
    fieldName.dispatchEvent(evt);
  }
}

我在其他问题中找到的信息是关于使ajax成为复合组件的内部部分,在这里我想要ajax分离,因为我可能在组件的其他用途中不需要它。

我正在使用JBoss 6.1与Mojarra 2.1.9和Richfaces 4。

提前致谢。

更新:

即使找到了jarek.jpa的答案权,如果有人想检查代码,请点击此处:

复合组件 http://pastebin.com/9wqMVfR5

主要形式 http://pastebin.com/i39ys2D9

1 个答案:

答案 0 :(得分:1)

这可能与设置为true的“readonly”属性有关。虽然您设法手动发送更改事件(JS),但由于只读状态,可能会丢弃侦听器的服务器端处理。参见例如jsf (richfaces) readonly input text validation