Il existe plusieurs façons de répondre à l'exigence.
Si votre servletcontainer prend en charge un minimum de Servlet 3.0 / EL 2.2, passez-le simplement comme argument de la méthode action / listener du UICommand
composant ou de la AjaxBehavior
balise. Par exemple
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
En combinaison avec:
public void insert(Long id) {
// ...
}
Cela nécessite uniquement que le modèle de données soit conservé pour la demande d'envoi de formulaire. Le mieux est de placer le bean dans la portée de la vue par @ViewScoped
.
Vous pouvez même transmettre tout l'objet d'élément:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
avec:
public void insert(Item item) {
// ...
}
Sur les conteneurs Servlet 2.5, cela est également possible si vous fournissez une implémentation EL qui prend en charge cela, comme JBoss EL. Pour plus de détails sur la configuration, consultez cette réponse .
Utilisation <f:param>
en UICommand
composant. Il ajoute un paramètre de requête.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
Si votre bean a une portée de requête, laissez JSF le définir par @ManagedProperty
@ManagedProperty(value="#{param.id}")
private Long id; // +setter
Ou si votre bean a une portée plus large ou si vous voulez une validation / conversion plus fine, utilisez-la <f:viewParam>
sur la vue cible, voir aussi f: viewParam vs @ManagedProperty :
<f:viewParam name="id" value="#{bean.id}" required="true" />
Dans tous les cas, cela présente l'avantage que le modèle de données n'a pas nécessairement besoin d'être conservé pour l'envoi du formulaire (dans le cas où votre bean est limité à la requête).
Utilisation <f:setPropertyActionListener>
en UICommand
composant. L'avantage est que cela supprime le besoin d'accéder à la mappe de paramètres de requête lorsque le bean a une portée plus large que la portée de la requête.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
En combinaison avec
private Long id; // +setter
Il sera uniquement disponible par propriété id
dans la méthode d'action. Cela nécessite uniquement que le modèle de données soit conservé pour la demande d'envoi de formulaire. Le mieux est de placer le bean dans la portée de la vue par @ViewScoped
.
Liez la valeur datatable à la DataModel<E>
place qui à son tour encapsule les éléments.
<h:dataTable value="#{bean.model}" var="item">
avec
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
(le créer transient
et l'instancier paresseusement dans le getter est obligatoire lorsque vous l'utilisez sur un bean à portée de vue ou de session car il DataModel
n'est pas implémenté Serializable
)
Ensuite, vous pourrez accéder à la ligne actuelle DataModel#getRowData()
sans rien passer (JSF détermine la ligne en fonction du nom du paramètre de demande du lien / bouton de commande cliqué).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
Cela nécessite également que le modèle de données soit conservé pour la demande d'envoi de formulaire. Le mieux est de placer le bean dans la portée de la vue par @ViewScoped
.
Utilisez Application#evaluateExpressionGet()
pour évaluer le courant par programme #{item}
.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
La manière de choisir dépend des exigences fonctionnelles et du fait que l'une ou l'autre offre plus d'avantages à d'autres fins. Personnellement, j'irais de l'avant avec le n ° 1 ou, si vous souhaitez également prendre en charge les conteneurs de servlet 2.5, avec le n ° 2.