2013-03-06 45 views
7

Primefaces 3.5, Mojarra 2.1.14. Đây là DataTable PF của tôi, nó có chứa một cột boolean không thể chỉnh sửa tên 'tự động', và có thể chỉnh sửa 'nhãn' cột:Cách cập nhật hàng cụ thể trong Primefaces datatable

<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> 

di động chỉnh sửa sự kiện nghe:

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(); 
     } 
    } 
} 

Các tế bào công trình biên tập, gửi dữ liệu đến người nghe và nó được lưu giữ chính xác đến cơ sở dữ liệu. Cờ 'tự động' cũng bị xóa bởi trình lắng nghe sự kiện chỉnh sửa ô và được duy trì chính xác đến cơ sở dữ liệu. Vấn đề là hộp kiểm 'tự động' không được cập nhật trên máy khách.

Tôi cũng đã cố gắng

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

đó cập nhật một cách chính xác vào hộp kiểm, nhưng cũng gây chú trọng bị mất, và chất thải băng thông.

Làm cách nào để cập nhật chỉ một ô cụ thể sau khi sự kiện cellEdit được kích hoạt?

Trả lời

5

Bạn p:ajax thẻ nằm bên trong p:dataTable không có trong một số hàng hoặc cột cụ thể, do đó bạn có thể dễ dàng cập nhật một số id thành phần tương đối. Bạn có thể với sự giúp đỡ của RequestContext cập nhật thành phần cụ thể trong ô. Vì vậy, loại bỏ update từ p:ajax và thêm video này vào phương pháp onEditLabel của bạn:

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

Như bạn thấy, id của thành phần bên trong tế bào có số lượng hàng trước khi id bạn đã gán.

+0

Cảm ơn! Điều này làm việc, nhưng chắc chắn không phải là thực hành tốt nhất. Đầu tiên, tôi dựa vào quy ước đặt tên thành phần id cụ thể. Thứ hai, bean điều khiển của tôi bây giờ chứa logic frontend (xem ID). Giải pháp tốt nhất là thêm một tính năng như vậy vào PF DataTable. Thở dài. :) – rootkit

+1

Tôi hoàn toàn không đồng ý với bạn. Backing bean được kết hợp chặt chẽ với lớp trình bày (ví dụ như của bạn từ phương thức gọi phương thức sao lưu cuộc gọi AJAX). Nó sẽ là xấu nếu bạn đặt logic kinh doanh trong đậu ủng hộ. Tôi đồng ý rằng việc đặt id trong bean sao lưu không phải là rất tốt đẹp, nhưng trong thời điểm này tôi không thấy bất kỳ giải pháp dễ dàng nào. – partlov

+0

Tôi đồng ý không có giải pháp dễ dàng, điều này sẽ phải làm. Cảm ơn một lần nữa! – rootkit

2

Tôi tin rằng bạn có thể giải quyết vấn đề này mà không cần phải biết chi tiết về ID của thành phần bạn muốn cập nhật. Bạn có thể chuyển nó như một tham số cho bean.

Trước tiên, hãy liên kết thành phần bạn muốn cập nhật. Bạn không thực sự cần một bean mà thành phần này bị ràng buộc. Bạn chỉ cần xác định một số giá trị mà bạn có thể sử dụng để xác định thành phần này sau trong JSF của bạn. Vì vậy, trong trường hợp của bạn, bạn sẽ làm điều gì đó như:

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

Bây giờ truy cập thành phần khi bạn cập nhật. tức là:

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

Bây giờ bạn có thể cập nhật thành phần từ phương thức sự kiện cellEdit của bạn mà không biết nội dung của ID. tức là:

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

Bạn đã thực sự thử điều này chưa? Tôi tự hỏi nếu thành phần ràng buộc sẽ làm việc một cách chính xác bên trong một datatable. Ngoài ra tôi tin rằng bạn có thể sử dụng một cái gì đó như # {component.clientId}, xem http: // stackoverflow.com/questions/4469992/how-to-get-id-of-gọi-thành phần-in-the-getter-phương pháp – rootkit

+0

Tình hình của tôi là một chút khác nhau, vì vậy tôi đã không cố gắng chính xác kịch bản này, nhưng tôi đã làm một cái gì đó rất tương đồng. Tôi tin rằng nó sẽ làm việc cho kịch bản được đăng ở đây. Và vâng. Thành phần ràng buộc không hoạt động bên trong một datatable. Đó là gần gũi hơn với kịch bản của tôi thực sự như tôi muốn cập nhật ID của một nút trong một hàng của một bảng, nhưng gặp khó khăn khi thực hiện nó vì các hàng trong bảng là động và do đó là ID của nút. Thông qua ID của thành phần trong thời trang này là giải pháp tốt nhất tôi có thể tìm thấy. –

Các vấn đề liên quan