如何更新Primefaces数据表中的特定行

时间:2013-03-06 20:40:53

标签: primefaces

Primefaces 3.5,Mojarra 2.1.14。这是我的PF数据表,它包含一个名为'automatic'的不可编辑的布尔列,以及可编辑的'label'列:

<p:dataTable value="#{bean.contents}" paginator="true" var="row" 
  editable="true" editMode="cell" rows="25" rowsPerPageTemplate="10,25,50" id="list">
    <p:column>
        <f:facet name="header"><h:outputText value="header1" /></f:facet>
        <p:selectBooleanCheckbox value="#{row.automatic}" disabled="true" id="isAutomatic"></p:selectBooleanCheckbox>
    </p:column>
    <p:column>
        <f:facet name="header"><h:outputText value="header2" /></f:facet>
        <p:cellEditor>
            <f:facet name="output">
                <h:outputText value="#{row.label}"></h:outputText>
            </f:facet>
            <f:facet name="input">
                <p:inputText value="#{row.label}"></p:inputText>
            </f:facet>
        </p:cellEditor>
    </p:column>
    <p:ajax event="cellEdit" process="@this" listener="#{myBean.onEditLabel}" update="isAutomatic"/>
</p:dataTable>

单元格编辑事件监听器:

public void onEditLabel(CellEditEvent event) {
    Object oldValue = event.getOldValue();
    Object newValue = event.getNewValue();

    if(newValue != null && !newValue.equals(oldValue)) {
        DataTable s = (DataTable) event.getSource();
        MyEntity d = (MyEntity) s.getRowData();
        try {
            d.setAutomatic(false);
            myDAO.save(d);
            addMessage("Change saved!");
        } catch (Exception ex) {
            addErrorMessage("Label could not be saved!");
            getFacesContext().validationFailed();
        }
    }
}   

单元格编辑器工作,将数据发送到侦听器,并将其正确保存到数据库。单元格编辑事件监听器也会清除“自动”标志,并将其正确保存到数据库中。问题是客户端上没有更新“自动”复选框。

我也试过

    <p:ajax event="cellEdit" process="@this" listener="#{myBean.onEditLabel}" update="list"/>

正确更新了复选框,但也导致焦点丢失,浪费带宽。

如何在触发cellEdit事件后更新特定单元格?

2 个答案:

答案 0 :(得分:5)

p:ajax标记位于某个特定行或列的p:dataTable内,因此您可以轻松更新一些相对组件ID。您可以借助RequestContext更新单元格中的特定组件。因此,从update移除p:ajax并将其添加到您的onEditLabel方法中:

RequestContext.getCurrentInstance().update(
  s.getClientId(FacesContext.getCurrentInstance()) +
  ":" + event.getRowIndex() +
  ":isAutomatic"
);

如您所见,单元格内部组件的ID在您指定的ID之前具有行号。

答案 1 :(得分:2)

我相信您无需了解要更新的组件ID的详细信息即可解决此问题。您可以将它作为参数传递给bean。

首先,绑定要更新的组件。您实际上并不需要此组件绑定到的bean。您只需要定义一些值,以便稍后在JSF中识别此组件。所以在你的情况下,你会做类似的事情:

<p:selectBooleanCheckbox binding="#{isAutomaticComponent}" value="#{row.automatic}" disabled="true" id="isAutomatic"></p:selectBooleanCheckbox>

现在,在进行更新时访问该组件。即:

<p:ajax event="cellEdit" process="@this" listener="#{myBean.onEditLabel(isAutomaticComponent.clientId)}" />

现在,您可以在不知道ID内容的情况下从cellEdit事件方法更新组件。即:

public void onEditLabel(CellEditEvent event, String idOfComponentToUpdate) {
...
RequestContext.getCurrentInstance().update(idOfComponentToUpdate);
...