Es gibt verschiedene Möglichkeiten, um die Anforderung zu erfüllen.
Wenn Ihr Servletcontainer mindestens Servlet 3.0 / EL 2.2 unterstützt, übergeben Sie ihn einfach als Argument für die Aktion / Listener-Methode der UICommand
Komponente oder des AjaxBehavior
Tags. Z.B
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
In Kombination mit:
public void insert(Long id) {
// ...
}
Dies erfordert nur, dass das Datenmodell für die Formularübermittlungsanforderung erhalten bleibt. Am besten setzen Sie die Bean in den Ansichtsbereich von @ViewScoped
.
Sie können sogar das gesamte Objekt übergeben:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
mit:
public void insert(Item item) {
// ...
}
Auf Servlet 2.5-Containern ist dies auch möglich, wenn Sie eine EL-Implementierung bereitstellen, die dies unterstützt, z. B. JBoss EL. Einzelheiten zur Konfiguration finden Sie in dieser Antwort .
Verwendung <f:param>
in UICommand
Komponenten. Es wird ein Anforderungsparameter hinzugefügt.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
Wenn Ihre Bean einen Anforderungsbereich hat, lassen Sie sie von JSF festlegen @ManagedProperty
@ManagedProperty(value="#{param.id}")
private Long id; // +setter
Oder wenn Ihre Bean einen breiteren Bereich hat oder wenn Sie eine feinkörnigere Validierung / Konvertierung wünschen, verwenden Sie sie <f:viewParam>
in der Zielansicht , siehe auch f: viewParam vs @ManagedProperty :
<f:viewParam name="id" value="#{bean.id}" required="true" />
In beiden Fällen hat dies den Vorteil, dass das Datenmodell nicht unbedingt für das Senden des Formulars beibehalten werden muss (für den Fall, dass Ihre Bean einen Anforderungsbereich hat).
Verwendung <f:setPropertyActionListener>
in UICommand
Komponenten. Der Vorteil besteht darin, dass der Zugriff auf die Anforderungsparameterzuordnung nicht mehr erforderlich ist, wenn die Bean einen breiteren Bereich als den Anforderungsbereich hat.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
In Kombination mit
private Long id; // +setter
Es ist nur nach Eigenschaft id
in Aktionsmethode verfügbar . Dies erfordert nur, dass das Datenmodell für die Formularübermittlungsanforderung erhalten bleibt. Am besten setzen Sie die Bean in den Ansichtsbereich von @ViewScoped
.
Binden Sie DataModel<E>
stattdessen den datierbaren Wert an, der wiederum die Elemente umschließt.
<h:dataTable value="#{bean.model}" var="item">
mit
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
( transient
Wenn Sie dies in einer Bean mit Ansicht oder Sitzungsbereich verwenden, ist es obligatorisch, es im Getter zu erstellen und träge zu instanziieren, da DataModel
es nicht implementiert wird. Serializable
)
Anschließend können Sie auf die aktuelle Zeile zugreifen, DataModel#getRowData()
indem Sie nichts weitergeben (JSF ermittelt die Zeile anhand des Anforderungsparameternamens des angeklickten Befehlslinks / der angeklickten Schaltfläche).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
Dies erfordert auch, dass das Datenmodell für die Formularübermittlungsanforderung beibehalten wird. Am besten setzen Sie die Bean in den Ansichtsbereich von @ViewScoped
.
Verwenden Sie Application#evaluateExpressionGet()
diese Option, um den Strom programmgesteuert auszuwerten #{item}
.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
Welche Art zu wählen ist, hängt von den funktionalen Anforderungen ab und davon, ob die eine oder andere mehr Vorteile für andere Zwecke bietet. Ich persönlich würde mit # 1 fortfahren, oder, wenn Sie auch Servlet 2.5-Container unterstützen möchten, mit # 2.