Wie zeige ich eine Liste von Elementen und die Länge der Liste mit Wicket an, ohne dass ich die Liste zweimal erzeugen muss?
Für die Liste würde man ein LoadableDetachableModel benutzen und in load() das Ergebnis zurückliefern.
final LoadableDetachableModel<List<Something>> modelListe = new LoadableDetachableModel<List<Something>>()
{
@Override
protected List<Something> load()
{
return Something.asList();
}
};
Für die Anzahl der Einträge würde ich jetzt auf dieses Modell zurückgreifen:
LoadableDetachableModel<Integer> modelAnzahl = new LoadableDetachableModel<Integer>()
{
@Override
protected Integer load()
{
return modelListe.getObject().size();
}
@Override
public void detach()
{
modelListe.detach();
super.detach();
}
};
Wenn modelListe nicht mit einer Wicketkomponente verbunden wäre, würde detach für diese Modell nie aufgerufen und die Liste damit nicht neu erzeugt. Änderungen an der Liste würden sich nicht sofort in der Anzeige wiederspiegeln. Daher muss man in dem Modell, dass mit einer Wicketkomponente verbunden ist auch detach für alle referenzierten Modelle aufrufen. Es gibt eine einfachere Lösung:
public abstract class CascadingLoadableDetachableModel<M,P> extends LoadableDetachableModel<M>
{
IModel<P> _parent;
public CascadingLoadableDetachableModel(IModel<P> parent)
{
super();
_parent=parent;
}
@Override
public void detach()
{
super.detach();
_parent.detach();
}
@Override
protected M load()
{
return load(_parent.getObject());
}
protected abstract M load(P parentModelData);
}
Man übergibt die Modell-Referenz im Konstruktor, bekommt die Modell-Daten automatisch als Methodenparameter und detach wird auch automatisch aufgerufen:
CascadingLoadableDetachableModel<Integer,List<Something>> modelAnzahl = new CascadingLoadableDetachableModel<Integer,List<Something>>()
{
@Override
protected Integer load(List<Something> parentModelData)
{
return parentModelData.size();
}
};
Schön kurz.