2013-03-06 74 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

相關問題