【问题标题】:primefaces datatable rowedit not updating cell elementprimefaces数据表行编辑不更新单元格元素
【发布时间】:2014-01-20 23:49:48
【问题描述】:

我有一个带有 rowedit 的数据表。 我的表的一列是一个带有列表框的单元格,列表框的项目是动态检索的(取决于另一个单元格中的值) 我使用 rowEditInit 来设置 selectedrow 项目。我想更新列表框以检索正确的值。 这不起作用。 当我这样做时

<p:ajax event="rowEditInit" listener="#{workOrderDetail.onEdit}" update="orderitemstable" />

然后,当我单击铅笔图标时,我可以看到行切换到编辑模式并检索列表框项目。但它直接切换回非编辑模式。

但是当我这样做时

<p:ajax event="rowEditInit" listener="#{workOrderDetail.onEdit}" update="rmactionenumid" />

然后单击铅笔图标将该行置于编辑模式,但不会调用检索列表框项目。我的猜测是,它不会触发 rmactionenumid 上的更新。

有什么想法吗?

罗尔

这是我的 jsf 代码

            <p:ajax event="rowEditInit" listener="#{workOrderDetail.onEdit}" update="rmactionenumid" />


            <p:column >  
                <p:cellEditor>  
                    <f:facet name="output">  
                        <h:outputText id="rmactionenumidlabel" value="#{orderItem.rmActionRepr}" >
                        </h:outputText>
                    </f:facet>  
                    <f:facet name="input">  
                        <h:selectOneListbox id="rmactionenumid" value="#{orderItem.rmActionEnumId}" size="1" valueChangeListener="#{workOrderDetail.setActionRepr}">
                            <f:selectItems value="#{workOrderDetail.actionItems}"/> 
                            <p:ajax event="change" update="partdiscount,labourdiscount,totalprice,:detail:wodetail:totals" execute="@this"  />                                  
                        </h:selectOneListbox>   

                    </f:facet>  
                </p:cellEditor>  
            </p:column>
<p:column >
<p:rowEditor id="edit"  />                          
                </p:commandLink>

            </p:column>  
        </p:dataTable>

这是我的 java bean 代码

public List<SelectItem> getActionItems() throws MWSException {
    ArrayList<SelectItem> actions = new ArrayList<SelectItem>();
    if (getSelectedOrderItem() != null) {

        ListManager lm = new ListManager(getWA().getMwsProxy());
        MWSGenericMapList items = lm.nativeSearch(getWS().getUser(), HdfWebConstants.NS_VEHICLEPARTACTIONS, 0, 0, 200,
                false, getSelectedOrderItem().getVehiclePartCode());

        for (int i = 0; i < items.size(); i++) {
            actions.add(new SelectItem(items.get(i).get("rmaction_enumid").toString(), items.get(i).get("rmaction")
                    .toString()));
        }

    }
    return actions;
}

public void setSelectedOrderItem(IMWSOrderItem newSelectedOrderItem) throws MWSException {
    this.selectedOrderItem = newSelectedOrderItem;
}

public void onEdit(RowEditEvent event) throws MWSException {

    setSelectedOrderItem((IMWSOrderItem) event.getObject());

}

我正在使用 PF3.5

【问题讨论】:

  • 你为什么在selectOneListbox同时使用valueChangeListenerp:ajax?您有很多代码可以发布您的功能,例如,您在开始编辑和完成编辑时调用onEdit。真的有用吗?此外,您发布了两个内容相似的专栏,我建议您尝试自己隔离具体问题。如果您仍然遇到问题,请以更可取的SSCCE 样式在此处发布,该样式可以复制粘贴并运行。否则,看具体问题太复杂了。
  • 我删除了一些代码(认为它可能有用,但显然没有)
  • 如果我使用 ajax 添加一个命令链接,只需 update="rmactionenumid" 并在编辑后单击它,然后正确显示 de 列表框(无需再次调用 bean 方法)

标签: jsf primefaces datatable listbox


【解决方案1】:

它失败了,因为update="rmactionenumid" 在这个结构中是相对于表本身,而不是相对于当前表行。

基本上,它正在寻找具有客户端 ID formId:tableId:rmactionenumid 的组件,而不是例如第二行formId:tableId:1:rmactionenumid。从技术上讲,&lt;p:ajax&gt; 应该放在&lt;p:column&gt; 内,但这不适用于rowEditInit 事件。

您需要根据UIData 组件(可用作RowEditEvent 参数)编写自己的update 客户端ID,并将组合的客户端ID 添加到PartialViewContext#getRenderIds()

因此,删除&lt;p:ajax update&gt; 并扩展onUpdate() 方法如下:

public void onEdit(RowEditEvent event) {
    UIData table = (UIData) event.getComponent();
    String updateClientId = table.getClientId() + ":" + table.getRowIndex() + ":rmactionenumid";
    FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(updateClientId);

    // ...
}

【讨论】:

    【解决方案2】:

    按照 BalusC 的回答:

    由于您使用的是 Primefaces 3.5,您可以选择使用它的实用程序类 ComponentUtils 和 RequestContext:

    String actId = ComponentUtils.findComponentClientId( "rmactionenumid" );
    RequestContext.getCurrentInstance().update( actId );
    

    将与 BalusC 发布的 sn-p 执行相同的操作。

    【讨论】:

      【解决方案3】:

      天哪,我花了很长时间才弄清楚这一点。 BalusC 一如既往地死气沉沉,但让我无法理解的是更新 Datatable 并没有像我预期的那样更新它的所有子项。更新表实际上会更新行(基础模型中的已删除行消失)并重新排序行,如果基础模型已重新排序,但 CellEditor 容器内的 outputText 小部件中的值不会更新,除非您提供一个&lt;p:ajax /&gt;标签给那些你想更新的人,在我的例子中是所有的人。我猜有一个设计假设,当 CellEditor 启动 Ajax 调用时,Datatable 父级只会更新已编辑的子单元格。我一直不明白为什么 CellEditor 需要同时包含 InputText 和 OutputText 才能工作。

      当多个用户在不同会话中同时编辑同一个数据表时,这给我带来了可怕的问题。 UserA 将进行编辑并获得正确更新的表,可能具有不同顺序的行。然后,其 Datatable 现在已过期的 UserB 将进行编辑,并且该编辑将正确保存到数据库中(因为该行具有唯一的隐藏 ID),但该编辑将转到 Datatable 中的错误行(但正确的列)和 UserB,即使在更新之后,也不会在不同的单元格中看到 UserA 的更改。一旦我将&lt;p:ajax update="datatableID" /&gt; 标签放在 inputText 正文中,它就可以正常工作。我仍然有必须单独解决的并发问题,但至少 Datatable 在编辑后是正确的。

      BalusC,如果你在外面,请在这里纠正我的错误假设。

      【讨论】:

      【解决方案4】:

      我也遇到过同样的问题。您可以执行以下操作:

      在您的更新方法下放置一个记录器对象,(或者您可以简单地编写一个 system.out.println)来检查您的方法是否可以从 jsf 页面访问。如果是这样,请在此处写下您的操作。

      对我来说,我检查了我的方法是否被访问。在我看到之后,我的行记录仍然没有得到更新。我所做的是在方法下创建一个新的desired-row对象,并通过getter/setter将行值的内容复制到我的新对象中。然后我可以更新我的行。这种方式适合我。

      【讨论】:

        【解决方案5】:

        它可能对某人有所帮助。我有一个类似的问题,我在互联网上尝试了所有可能的事情。最终我放弃了,但后来不小心把它修好了。问题是我的 .xhtml 中使用了多个 并且由于某种原因没有传播更改。 希望它可以帮助某人。

        【讨论】:

          猜你喜欢
          • 2014-08-03
          • 1970-01-01
          • 2017-10-23
          • 2013-05-16
          • 1970-01-01
          • 1970-01-01
          • 2011-09-15
          • 1970-01-01
          • 2017-07-02
          相关资源
          最近更新 更多