Istnieje kilka sposobów spełnienia tego wymagania.
Jeśli twój servletcontainer obsługuje co najmniej Servlet 3.0 / EL 2.2, to po prostu przekaż go jako argument metody działania / detektora UICommand
komponentu lub AjaxBehavior
tagu. Na przykład
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
W połączeniu z:
public void insert(Long id) {
// ...
}
Wymaga to jedynie zachowania modelu danych dla żądania przesłania formularza. Najlepiej jest umieścić fasolę w zakresie widoku według @ViewScoped
.
Możesz nawet przekazać cały przedmiot:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
z:
public void insert(Item item) {
// ...
}
W kontenerach Servlet 2.5 jest to również możliwe, jeśli dostarczysz implementację EL, która to obsługuje, na przykład JBoss EL. Szczegółowe informacje na temat konfiguracji można znaleźć w tej odpowiedzi .
Użyj <f:param>
w UICommand
komponencie. Dodaje parametr żądania.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
Jeśli Twój bean ma zakres żądania, pozwól JSF ustawić go według @ManagedProperty
@ManagedProperty(value="#{param.id}")
private Long id; // +setter
Lub jeśli twój bean ma szerszy zakres lub jeśli chcesz dokładniejszej weryfikacji / konwersji, użyj <f:viewParam>
w widoku docelowym, zobacz także f: viewParam vs @ManagedProperty :
<f:viewParam name="id" value="#{bean.id}" required="true" />
Tak czy inaczej, ma to tę zaletę, że model danych nie musi być koniecznie zachowywany w celu przesłania formularza (w przypadku, gdy komponent bean jest objęty zakresem żądań).
Użyj <f:setPropertyActionListener>
w UICommand
komponencie. Zaletą jest to, że eliminuje to potrzebę uzyskiwania dostępu do mapy parametrów żądania, gdy komponent bean ma szerszy zakres niż zakres żądania.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
W połączeniu z
private Long id; // +setter
Będzie dostępny tylko według właściwości id
w metodzie akcji. Wymaga to jedynie zachowania modelu danych dla żądania przesłania formularza. Najlepiej jest umieścić fasolę w zakresie widoku według @ViewScoped
.
Powiąż wartość datatable z, DataModel<E>
która z kolei zawija elementy.
<h:dataTable value="#{bean.model}" var="item">
z
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
(tworzenie jej transient
i leniwe tworzenie instancji w funkcji pobierającej jest obowiązkowe, gdy używasz tego w komponencie bean o zasięgu widoku lub sesji, ponieważ DataModel
nie implementuje Serializable
)
Wtedy będziesz mógł uzyskać dostęp do bieżącego wiersza DataModel#getRowData()
bez przekazywania czegokolwiek (JSF określa wiersz na podstawie nazwy parametru żądania klikniętego linku / przycisku polecenia).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
Wymaga to również zachowania modelu danych dla żądania przesłania formularza. Najlepiej jest umieścić fasolę w zakresie widoku według @ViewScoped
.
Służy Application#evaluateExpressionGet()
do programowej oceny bieżącego #{item}
.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
Wybór sposobu zależy od wymagań funkcjonalnych i od tego, czy jedno czy drugie zapewnia więcej korzyści do innych celów. Osobiście poszedłbym dalej z numerem 1 lub, jeśli chciałbyś również obsługiwać kontenery serwletów 2.5, z numerem 2.