具有2个相关selectOneMenus的dataTable中的Primefaces incell编辑不保存更改

时间:2012-06-19 08:16:50

标签: ajax jsf-2 primefaces

我有<p:dataTable>内嵌编辑,它包含2列,每列有<h:selectOneMenu>加上第三个编辑列。第二个<h:selectOneMenu>取决于第一个<h:selectOneMenu>中的选择。当一行处于输入/编辑模式时,更改第一个<h:selectOneMenu>中的值应更新第二个<h:selectoneMenu>中的列表,然后我应该能够继续更改第二个中的值,然后保存对行的更改。

我的问题是,如果第一个<h:selectOneMenu>中的值发生了更改,则第二个<p:selectOneMenu>中的列表会正确更新,但是当我点击{中的检查图标(保存更改)时没有任何反应{1}}列,该行保持编辑模式。支持bean中的RowEditEvent侦听器(显然)也没有被调用。我仍然可以点击关闭图标将行切换回输出模式,但是没有保存任何内容。

如果我只更改第二个<p:rowEditor>中的值而不更改第一个<h:selectOneMenu>中的值,则保存更改没有问题。

以下是代码片段,简化,并且由于测试代码的天数仍然“脏”:

<h:selectOneMenu>

xhtml:

<h:form id="dataListForm"> <p:dataTable id="dataTable" value="#{bean.rdcList}" var="rdc" > <p:ajax event="rowEdit" listener="#{bean.onRowEdit}" /> <f:facet name="header"> Data List </f:facet> <p:column headerText="Agency"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{rdc.agency.descr}" /> </f:facet> <f:facet name="input"> <h:selectOneMenu value="#{rdc.agency.id}" valueChangeListener="#{bean.agChanged}"> <f:selectItems value="#{bean.agenciestab}" var="ag" itemValue="#{ag.id}" itemLabel="#{ag}" /> <p:ajax event="change" update="zoneSelect" /> </h:selectOneMenu> </f:facet> </p:cellEditor> </p:column> <p:column headerText="Zone"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{rdc.zone.id} - #{rdc.zone.name}" /> </f:facet> <f:facet name="input"> <h:selectOneMenu id="zoneSelect" value="#{rdc.zone.id}" valueChangeListener="#{bean.zChanged}"> <f:selectItems value="#{bean.zonestab}" var="z" itemValue="#{z.id}" itemLabel="#{z}" /> </h:selectOneMenu> </f:facet> </p:cellEditor> </p:column> <p:column headerText="Edit"> <p:rowEditor /> </p:column> </p:dataTable>

bean:

我正在使用primefaces-3.1.1,mojarra-2.1.3-FCS和Tomcat 7.0.26

我哪里做错了?是否有更清洁,更好的方法来实现我想要实现的目标?

1 个答案:

答案 0 :(得分:2)

您在getter方法中执行业务逻辑。在您的特定情况下,每次调用数据表的getter时,都要将数据表行索引设置为0。这很可能是您具体问题的根本原因。这样,JSF就无法找到对第一行以外的行执行的任何操作。您绝对不应该在getter方法中执行业务逻辑。每当EL需要评估表达式时,就会调用getter方法,该表达式在中等大小的数据表中可能会达到几百次。

Getter方法的设计方式应该只是返回数据,仅此而已。

public List<Rdc> getRdcList() {
    return rdcList;
}

任何业务逻辑都应该在(action)侦听器方法的(post)构造函数中执行。首次初始化应该进入(post)构造函数,并且基于enduser(ajax)动作的一次性更改应该进入(动作)侦听器方法。在边缘情况下,您应该使用最高延迟加载。

另见:


对于具体问题,

无关valueChangeListener并非适用于您所在目的的正确工具。而是使用<p:ajax listener="#{bean.changed}">。该模型已在此时使用提交的值进行更新。