2013-03-06 57 views
7

Primefaces 3.5,Mojarra 2.1.14。这是我的PF数据表,它包含了一个名为“自动”一个不可编辑的布尔列,并编辑“标签”列:如何更新Primefaces数据表中的特定行

<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事件触发后更新特定单元格?

回答

5

p:ajax标记在里面p:dataTable没有在某些特定的行或列,所以你很容易更新一些相对的组件ID。您可以在RequestContext的帮助下更新单元格中的特定组件。所以,从p:ajax删除update并添加到您的onEditLabel方法:

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

正如你可以看到,里面电池组件的ID有你分配的id前行数。

+0

谢谢!这有效,但绝对不是最佳做法。首先,我依靠特定的组件id命名约定。其次,我的控制器bean现在包含前端逻辑(视图ID)。最好的解决方案是将这样的功能添加到PF DataTable中。叹。 :) – rootkit 2013-03-07 16:31:26

+1

我不完全同意你的看法。 Backing bean与表示层紧密结合(例如,您可以通过AJAX listener调用backing bean方法)。如果您将业务逻辑放入backing bean中,那将会很糟糕。我同意将id放在backing bean中并不是很好,但在这一刻我没有看到任何简单的解决方案。 – partlov 2013-03-07 18:11:41

+0

我同意没有简单的解决方案,这将不得不做。再次感谢! – rootkit 2013-03-07 18:27:06

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); 
... 
+0

你真的尝试过吗?我想知道组件绑定是否可以在数据表内正常工作。另外我相信你可以使用类似#{component.clientId}的东西,参见http:// stackoverflow。com/questions/4469992/how-to-get-id-call-component-in-the-getter-method – rootkit 2014-01-28 19:26:55

+0

我的情况有点不同,所以我没有尝试过这种情况,但我做了一些事情非常相似。我相信这将适用于此处发布的情景。是的。组件绑定在数据表内工作。这实际上更接近我的场景,因为我想更新表格中一行按钮的ID,但由于表格中的行是动态的,因此该按钮的ID也是如此,因此很难做到这一点。以这种方式传递组件的ID是我能找到的最佳解决方案。 – 2014-02-21 20:27:57

相关问题