Morgen,
folgende Annahme:
Ich lese eine Liste aus einer DB aus und kann an ihr Änderungen vornehmen. Sagen wir, ich kann in diesem Beispiel nur Elemente Löschen. Hinter jedem Listenelement ist eine Schaltfläche zum Entfernen. Es soll aber nicht für jedes Löschen ein DB-Aufruf erfolgen, sondern erst ganz am Ende, etwa wenn ein Bestätigungsknopf betätigt wird oder man die Seite wechselt. Hierzu muss ich die aktuelle Liste lokal vorhalten. Ich habe das so gelöst:
Eine index.xhtml:
Ein BackingBean Index:
folgende Annahme:
Ich lese eine Liste aus einer DB aus und kann an ihr Änderungen vornehmen. Sagen wir, ich kann in diesem Beispiel nur Elemente Löschen. Hinter jedem Listenelement ist eine Schaltfläche zum Entfernen. Es soll aber nicht für jedes Löschen ein DB-Aufruf erfolgen, sondern erst ganz am Ende, etwa wenn ein Bestätigungsknopf betätigt wird oder man die Seite wechselt. Hierzu muss ich die aktuelle Liste lokal vorhalten. Ich habe das so gelöst:
Eine index.xhtml:
HTML:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Beispiel</title>
</h:head>
<h:body>
<h:form>
<h:dataTable value="#{index.list}" var="entry">
<h:column>
#{entry}
</h:column>
<h:column>
<h:commandButton actionListener="#{index.delete}" value="Entfernen">
<f:attribute name="selected" value="#{entry}" />
</h:commandButton>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
Ein BackingBean Index:
Java:
package backing;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.context.Flash;
import javax.faces.event.ActionEvent;
public class Index
{
private List list;
private Flash flash;
private String selected;
@PostConstruct
private void postConstruct ()
{
if(flash.get("list") == null)
{
ArrayList arrayList = new ArrayList();
arrayList.add("Element 1");
arrayList.add("Element 2");
arrayList.add("Element 3");
flash.putNow("list", arrayList);
list = arrayList;
}
else
{
flash.keep("list");
list = (List) flash.get("list");
}
}
public void delete (ActionEvent actionEvent)
{
selected = (String) actionEvent.getComponent().getAttributes().get("selected");
list.remove(selected);
}
// außerdem noch die üblichen Getter und Setter, die ich aus Übersichtsgründen mal unterschlage
}
[/Java]
Hier noch der Eintrag in der faces-config.xml:
[XML]
<managed-bean>
<managed-bean-name>index</managed-bean-name>
<managed-bean-class>backing.Index</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>flash</property-name>
<value>#{flash}</value>
</managed-property>
</managed-bean>
[/XML]
Ich hab jetzt schon alles mögliche getestet und rumprobiert, aber es hilft alles nichts, nach der ersten Aktion werden die Einträge nicht mehr richtig gelöscht. Entweder es passiert nichts, Ein Eintrag der beim letzten Mal gelöscht wurde wird gegen den getauscht, den man dieses Mal löschen will, man kann es auch hinbekommen, dass ein bereits gelöschter wieder auftaucht! Es steckt irgendeine Logik dahinter, aber ich habe keine Lust das hier jetzt alles darzustellen. Wenn man das Bean langlebiger deklariert, Session- oder ViewScoped tritt das Problem nicht auf.
Ich glaube, dass es etwas mit dem Zeitpunkt der Beanerzeugung zu tun hat - die aktuelle Liste liegt noch nicht vor, wenn sie in der postConstruct-Methode geladen wird...
Kann mir jemand weiterhelfen?
Zuletzt bearbeitet von einem Moderator: