Ada beberapa cara untuk mencapai kebutuhan tersebut.
Jika servletcontainer Anda mendukung minimal Servlet 3.0 / EL 2.2, maka teruskan saja sebagai argumen metode aksi / pendengar dari UICommand komponen atau AjaxBehaviortag. Misalnya
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
Dikombinasikan dengan:
public void insert(Long id) {
// ...
}
Ini hanya mengharuskan model data dipertahankan untuk permintaan pengiriman formulir. Yang terbaik adalah meletakkan kacang dalam lingkup tampilan dengan @ViewScoped.
Anda bahkan dapat meneruskan seluruh objek item:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
dengan:
public void insert(Item item) {
// ...
}
Pada kontainer Servlet 2.5, ini juga dimungkinkan jika Anda menyediakan implementasi EL yang mendukung ini, seperti JBoss EL. Untuk detail konfigurasi, lihat jawaban ini .
Gunakan <f:param>dalam UICommandkomponen. Ini menambahkan parameter permintaan.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
Jika bean Anda adalah request scoped, biarkan JSF mengaturnya @ManagedProperty
@ManagedProperty(value="#{param.id}")
private Long id; // +setter
Atau jika bean Anda memiliki cakupan yang lebih luas atau jika Anda menginginkan validasi / konversi yang lebih terperinci , gunakan <f:viewParam>pada tampilan target, lihat juga f: viewParam vs @ManagedProperty :
<f:viewParam name="id" value="#{bean.id}" required="true" />
Bagaimanapun, ini memiliki keuntungan bahwa model data tidak perlu dipertahankan untuk pengiriman formulir (untuk kasus kacang Anda adalah cakupan permintaan).
Gunakan <f:setPropertyActionListener>dalam UICommandkomponen. Keuntungannya adalah ini menghilangkan kebutuhan untuk mengakses peta parameter permintaan ketika kacang memiliki cakupan yang lebih luas daripada ruang lingkup permintaan.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
Dikombinasikan dengan
private Long id; // +setter
Ini hanya akan tersedia dengan idmetode properti dalam tindakan. Ini hanya mengharuskan model data dipertahankan untuk permintaan pengiriman formulir. Yang terbaik adalah meletakkan kacang dalam lingkup tampilan dengan @ViewScoped.
Ikat nilai datatable ke nilai DataModel<E>yang akan membungkus item.
<h:dataTable value="#{bean.model}" var="item">
dengan
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
(membuatnya transientdan secara malas membuat instance di getter adalah wajib saat Anda menggunakan ini pada kacang cakupan tampilan atau sesi karena DataModeltidak diimplementasikan Serializable)
Kemudian Anda akan dapat mengakses baris saat ini DataModel#getRowData()tanpa melewatkan apa pun (JSF menentukan baris tersebut berdasarkan nama parameter permintaan dari tautan / tombol perintah yang diklik).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
Ini juga mensyaratkan bahwa model data dipertahankan untuk permintaan pengiriman formulir. Yang terbaik adalah meletakkan kacang dalam lingkup tampilan dengan @ViewScoped.
Gunakan Application#evaluateExpressionGet()untuk mengevaluasi arus secara terprogram #{item}.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
Cara mana yang dipilih tergantung pada persyaratan fungsional dan apakah yang satu atau yang lain menawarkan lebih banyak keuntungan untuk tujuan lain. Saya pribadi akan melanjutkan dengan # 1 atau, ketika Anda ingin mendukung kontainer servlet 2.5 juga, dengan # 2.