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 AjaxBehavior
tag. 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 UICommand
komponen. 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 UICommand
komponen. 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 id
metode 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 transient
dan secara malas membuat instance di getter adalah wajib saat Anda menggunakan ini pada kacang cakupan tampilan atau sesi karena DataModel
tidak 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.