2012-02-03 158 views
1

我建立的发票应用。当用户选择客户端时,与客户端关联的服务将通过ajax事件在dataTable中重新呈现。但是,dataTable中selectOneMenu的ajax事件不会触发。AJAX事件是由另一AJAX事件重新呈现不执行

这是让用户选择的客户机的形式:

<h:form> 
    <h:selectOneMenu id="clientSelect" value="#{invoiceBean.client}"> 
     <f:ajax execute="clientSelect" listener="#{invoiceServiceListener.processClientValueChange}" render=":test :invoiceData"/> 
     <f:selectItems value="#{invoiceBean.clientOptions}"/> 
    </h:selectOneMenu> 
</h:form> 

这将触发其填充在invoiceBean服务阵列和重新呈现显示所述服务在另一个selectOneMenu用于数据表的AJAX事件在dataTable中。这部分工作正常。

这是通过上述形式选择所述客户端之后被重新呈现的数据表:本selectOneMenu用于被适当地填充

<h:panelGroup id="test"> 
    <h:dataTable id="invoiceData" value="#{attributes.priceAttributes}" var="loop"> 
     <h:column> 
      <ui:param name="service" value="service#{loop}" /> 
      <ui:param name="description" value="description#{loop}" /> 
      <ui:param name="price" value="price#{loop}" /> 
      <h:form id="invoiceSelectMenu"> 
       <h:selectOneMenu id="selectMenu" value="#{invoiceBean[service]}"> 
        <f:ajax event="change" execute="selectMenu" listener="#{invoiceServiceListener.procesServiceValueChange}" render="@form" /> 
        <f:attribute name="row" value="#{loop}" /> 
        <f:selectItems value="#{invoiceBean.services}" /> 
       </h:selectOneMenu> 
       <h:inputText id="description" value="#{invoiceBean[description]}" /> 
       <h:inputText id="price" value="#{invoiceBean[price]}" /> 
       <h:outputText value="#{loop}" /> 
      </h:form> 
     </h:column> 
    </h:dataTable> 
</h:panelGroup> 

。但是,在选择一个菜单中的ajax事件在通过第一种形式重新呈现后不起作用。但是,如果我手动填充服务数组而未提交第一个表单,那么这个ajax事件正常执行。顺便说一下,这个ajax事件也为描述和价格输入字段设置了一个值,这些字段在事件发生时应该重新呈现。 invoiceBean是请求作用域。

+0

你为什么不阅读该邮件通过'['和']'格式化替换所有'<' and '>之前编辑的帮规'? – BalusC 2012-02-03 19:50:12

+0

如果您有DOM元素的事件处理程序并将其替换为AJAX内容,则不再附加事件。这是问题吗? – 2012-02-06 17:26:02

+0

对不起,我不熟悉这个DOM术语。你能详细说明一下吗?我如何解决这个问题?如果您有关于此事的链接,请分享。我很好的自己阅读,当我在谷歌搜索时,我无法找到一个有用的链接。谢谢。 – 2012-02-06 17:35:26

回答

2

这将是棘手的。由于JSF spec issue 790,当你重新渲染使用<f:ajax>另一<h:form>一些内容,那么它的视图状态会迷路。为了解决这个问题,你基本上需要引用内部<f:ajax>而不是某些成分含有的另一<h:form>完整的客户端ID。但是您基本上有多个表单,其中<h:dataTable>不能被绝对客户端ID引用。

你需要重新排列代码把<h:dataTable><h:form>,改变<f:ajax>execute只有必要的组件。

<h:form id="invoiceDataForm"> 
    <h:dataTable id="invoiceData" value="#{attributes.priceAttributes}" var="loop"> 
     <h:column> 
      <ui:param name="service" value="service#{loop}" /> 
      <ui:param name="description" value="description#{loop}" /> 
      <ui:param name="price" value="price#{loop}" /> 
      <h:selectOneMenu id="selectMenu" value="#{invoiceBean[service]}"> 
       <f:ajax execute="selectMenu,description,price" listener="#{invoiceServiceListener.procesServiceValueChange}" render="@form" /> 
       <f:attribute name="row" value="#{loop}" /> 
       <f:selectItems value="#{invoiceBean.services}" /> 
      </h:selectOneMenu> 
      <h:inputText id="description" value="#{invoiceBean[description]}" /> 
      <h:inputText id="price" value="#{invoiceBean[price]}" /> 
      <h:outputText value="#{loop}" /> 
     </h:column> 
    </h:dataTable> 
</h:panelGroup> 

,然后引用它形成第一形式,如下所示:在组件库特定Ajax引擎

<f:ajax execute="clientSelect" listener="#{invoiceServiceListener.processClientValueChange}" render=":invoiceDataForm" /> 

注意,如PrimeFaces一些组件库已经workarounded /解决了这个。所以,如果它可能发生,你已经在使用PrimeFaces,您还可以通过<p:ajax>代替第一种形式的<f:ajax>


无关到具体问题,<f:attribute name="row" value="#{loop}" />可能不是你所期望它做什么。它将设置null,因为<f:xxx>标签在视图生成时间期间运行,而不是在视图渲染时间标签期间运行。在查看构建时间期间,#{loop}不可用。但是,这对于受一个不同的问题:)

+0

谢谢BalusC先生。如果你碰巧读到这个,我应该用什么标签代替发送param到ajax事件?如果问题已经被问到,如果你有链接,我可以自己阅读。 – 2012-02-07 12:25:12

+0

嘿,我有另一个问题,与此有关。当我将渲染更改为“描述价格”时,它不再起作用。它只适用于@form,为什么? – 2012-02-07 16:51:11