2013-03-06 28 views
7

Primefaces 3.5, Mojarra 2.1.14. To jest mój PF DataTable zawiera ona jedną nieedytowalny kolumnę logiczną nazwie 'automatyczne' i edycji 'etykieta' kolumna:Jak zaktualizować określony wiersz w Primefaces, którego 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> 

komórkowych słuchacz edit event:

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

Cela prace Editor, wysyła dane do detektora i jest poprawnie przechowywane w bazie danych. Flaga "automatyczna" jest również czyszczona przez detektor zdarzeń edycji komórki i zostaje poprawnie utrwalona w bazie danych. Problem polega na tym, że pole wyboru "automatyczne" nie jest aktualizowane na kliencie.

Próbowałem też

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

które poprawnie zaktualizowane pole, ale również powoduje utratę ostrości i odpady przepustowości.

Jak mogę zaktualizować tylko określoną komórkę po uruchomieniu zdarzenia cellEdit?

Odpowiedz

5

Znacznik p:ajax jest wewnątrz p:dataTable nie w określonym wierszu lub kolumnie, więc cent tak łatwo zaktualizować jakiś względny identyfikator komponentu. Możesz za pomocą RequestContext zaktualizować określony komponent w komórce. Tak, usuń update z p:ajax i dodać do swojej metody onEditLabel:

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

Jak widać, identyfikator komponentu wewnątrz komórki posiada numer wiersza przed id przypisany.

+0

Dzięki! To działa, ale zdecydowanie nie jest najlepszą praktyką. Po pierwsze, polegam na konkretnej konwencji nazewnictwa identyfikatorów komponentów. Po drugie, mój komponent bean kontrolera zawiera teraz logikę frontendową (widoki ID). Najlepszym rozwiązaniem byłoby dodanie takiej opcji do PF DataTable. Westchnienie. :) – rootkit

+1

Nie całkowicie się z tobą zgadzam. Backing bean jest ściśle sprzężony z warstwą prezentacji (jak na przykład z metody wywołania AJAX wywołującego metodę bean backing). Byłoby źle, gdyby umieścić logikę biznesową w backingu. Zgadzam się, że umieszczenie id w podkładce nie jest bardzo przyjemne, ale w tej chwili nie widzę żadnego łatwego rozwiązania. – partlov

+0

Zgadzam się, że nie ma łatwego rozwiązania, to będzie musiało zrobić. Dzięki jeszcze raz! – rootkit

2

Uważam, że można rozwiązać ten problem bez konieczności podawania szczegółów identyfikatora komponentu, który ma zostać zaktualizowany. Możesz przekazać go jako parametr do komponentu bean.

Najpierw połącz element, który chcesz zaktualizować. Właściwie nie potrzebujesz fasoli, z którą ten komponent jest związany. Trzeba tylko zdefiniować jakąś wartość, której możesz użyć do zidentyfikowania tego komponentu później w twoim JSF. W twoim przypadku możesz zrobić coś takiego:

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

Teraz dostęp do komponentu podczas aktualizacji. tj:

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

Teraz możesz zaktualizować komponent z metody zdarzenia cellEdit bez znajomości treści identyfikatora. tj:

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

Czy próbowałeś tego? Zastanawiam się, czy powiązanie komponentów działałoby poprawnie w ramach datatable. Sądzę, że możesz użyć czegoś takiego jak # {component.clientId}, zobacz http: // stackoverflow.com/questions/4469992/how-to-get-id-of-calling-component-in-the-getter-method – rootkit

+0

Moja sytuacja jest trochę inna, więc nie próbowałem dokładnie tego scenariusza, ale zrobiłem coś bardzo podobna. Wierzę, że działałoby to w przypadku scenariusza zamieszczonego tutaj. I tak. Wiązanie komponentów działa w obrębie danych. Jest to bliższe mojemu scenariuszowi, ponieważ chciałem zaktualizować identyfikator przycisku w wierszu tabeli, ale miałem problem z tym, ponieważ wiersze w tabeli są dynamiczne, a więc również identyfikator przycisku. Przekazanie identyfikatora komponentu w ten sposób było najlepszym rozwiązaniem, jakie mogłem znaleźć. –

Powiązane problemy