JSF DataTable refreshen mit Ajax?

membersound

Bekanntes Mitglied
Hallo,

ich möchte eine <h:datatable> dynamisch nach dem Erstellen neuer Elemente refreshen.
Dafür habe ich 3 Ansätze, und wüsste gerne welcher zu Bevorzugen ist:

1. mit @Observes
Java:
public class Facade {

 private List<Customer> customerList;

 public void createNew() {
  service.create(newCustomer);
  event.fire(newCustomer);
 }
 
 public void onCustomerChanged(@Observes(notifyObserver = Reception.IF_EXISTS) final Customer newCustomer) {
  findAll();
 }

 @PostConstruct
 public void findAll() {
  customerList = service.findByNamedQuery("Customer.ALL");
 }

 public List<Customer> getCustomerList() {
  return customerList;
 }
}

2. oder aber lasse die observer weg, und rufe die findAll() direkt aus der create methode aus auf:
Java:
public void createNew() {
  service.create(newCustomer);
  findAll();
}

3. mit ajax
Java:
public void createNew() {
  service.create(newCustomer);
}

<h:form>
<h:commandButton id="register" action="#{facade.createNew()}" value="Register">
<f:ajax execute="@form" render = ":customerTable" />
</h:commandBUtton>
</h:form>

<h:datatable id="customerTable" var="_customer" value="facade.customerList">...

Das Problem hier ist: Ansatz 3 gefällt mir am besten, da kein zusätzliche Code in der Javaklasse notwendig ist. Nur funktioniert der Ajax-Ansatz so nicht! Denn da ich die findAll() methode hierbei weder über observer noch explizit aufrufe, wird customerList immer erst beim post-construct erneuert. Das führt dazu: ich füge Customer1 hinzu - nicht passiert. Ich füge Cust2 hinzu - die table wird aktualisiert und zeigt Cust1. usw.


Wie bekomme ich den Ansatz mit Ajax wie gewollt zum laufen?

Danke
 
möglichkeit 3 würde ich bevorzugen.
nach dem hinzufügen des neuen Customers, wird dieser auch der Liste hinzugefügt ?
(das sehe ich aus der Klasse nicht, da du es über Service machst)

i.d.r müsste es so gehen wie du es beschrieben hast.
Habe einige Webapplikationen, die so laufen.
ggf zeig mal bitte deine Service Klasse.
 
Nein, also die create Methode im Service persistiert den Customer bloß:
Java:
public Class service {

	public Customer create(Customer c) {
		this.em.persist(c);
		this.em.flush();
		this.em.refresh(c);
		return c;
	}

}

Das Problem ist ja folgendes: wenn ich ohne Ajax arbeite, dann wird mit dem Buttonslick meine komplette Page neu geladen. Dh über das @PostConstruct wird damit automatisch ein findAll() ausgeführt, sodass die CustomerList geupdatet wird.
Wenn ich aber mit Ajax arbeite, dann entfällt das neuladen der Page ja. Dh das PostConstruct bringt mir da nichts mehr, weil ja nur ein Teil der Page neu gerendert wird. Was ich ja auch beabsichtige - nämlich nur eine Tabelle mit CustomerDetails.
Dh aber auch: ich muss mich selbst darum kümmern, dass die findAll() innerhalb der createNew() Methode in der Facade ausgeführt wird. Denn sonst wird meine customerList ja nicht geupdatet.

Sprich: nach meinem obigen Beispiel muss ich 2) + 3) aus meinem Ausgangsposting kombinieren. Richtig? Oder geht es besser/einfacher?

Oder anders gesagt: ich würde mir das gerne sparen, immer mich darum kümmern zu müssen dass die customerList geupdatet wird.
Ich muss ja quasi für jede Methode in meiner Facade, die etwas am Customer-Objekt ändert, die findAll() Methode ausführen. Was je nach Umfang zu einer ganzen Menge doppeltem Code führt. In meinem Beispiel zugegeben vernachlässigbar klein, aber mir geht es hier ja eher ums Prinzip. Denn funktionieren tut es so ja auch. Ist mMn eben nur irgendwie unelegant.

Java:
@Named
@RequestScoped
public class Facade {

	@Inject
	private Service<Customer> service;

	@Inject
	private Customer newCustomer;

	private List<Customer> customerList;

	@PostConstruct
	public void findAll() {
		customerList = service.findByNamedQuery("Customer.ALL");
	}

	public void createNew() {
		service.create(newCustomer);
		findAll();
	}
}
 
Hallo,

du must nur das neue Customer Objekt deiner Liste in der Klasse Facade hinzufügen nachdem du es persistent gemacht hast.
customerList.add(newCustomer);
somit brauchst du nicht noch einmal die Komplette Datenbank abzufragen, spart auch performance 🙂
und bei delete:
customerList.remove(oldCustomer);
 
Ok das ist schonmal gut zu wissen, danke!

Aber dh auch, im muss mich immer selbst drum kümmern die Liste uptodate zu halten? Das kann man nicht "automatisieren"?
 
Guten Morgen,

habe eben noch einmal in die Bücher geschaut und nichts gefunden 🙁
wirst leider nicht herum kommen deine Liste anschließend selbst du aktualisieren.
Denke das die
liste.add(Object);
liste.remove(Object);
Funktionaufrufe nicht so wild sind (nur pro Vorgang einen Funktionaufruf -> createCustomer und deleteCustomer)

Wenn du das Objekt manuell deiner Liste hinzufügst, benötigst du auch keine erneute sql Abfrage, ebenso beim delete.
spart kosten und Zeit 🙂

Grüße und Danke für das Danke
lg Sence
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben