Ini valueChangeListenerhanya akan dipanggil ketika formulir dikirimkan dan nilai yang dikirimkan berbeda dari nilai awal. Oleh karena itu, ini tidak dipanggil ketika hanyachange event HTML DOM yang diaktifkan. Jika Anda ingin mengirimkan formulir selama changeacara DOM HTML , Anda harus menambahkan <f:ajax/>formulir lain tanpa listener (!) Ke komponen input. Ini akan menyebabkan pengiriman formulir yang hanya memproses komponen saat ini (seperti di execute="@this").
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
Saat menggunakan, <f:ajax listener>bukan valueChangeListener, secara default akan dieksekusi selama changeperistiwa DOM HTML . Di dalam UICommandkomponen dan komponen masukan yang mewakili kotak centang atau tombol radio, ini akan dijalankan secara default selama clickperistiwa DOM HTML saja.
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
Perbedaan utama lainnya adalah bahwa valueChangeListenermetode tersebut dipanggil selama akhir PROCESS_VALIDATIONSfase. Saat itu, nilai yang dikirimkan belum diperbarui dalam model. Jadi Anda tidak bisa mendapatkannya hanya dengan mengakses properti kacang yang terikat ke komponen masukan value. Anda harus melakukannya ValueChangeEvent#getNewValue(). Nilai lama dengan cara juga tersedia oleh ValueChangeEvent#getOldValue().
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
}
The <f:ajax listener>Metode dipanggil selama INVOKE_APPLICATIONfase. Saat itu, nilai yang dikirimkan sudah diperbarui dalam model. Anda bisa mendapatkannya dengan langsung mengakses properti kacang yang terikat ke komponen masukan value.
private Object value;
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value);
}
Selain itu, jika Anda perlu memperbarui properti lain berdasarkan nilai yang dikirimkan, maka itu akan gagal saat Anda menggunakan valueChangeListenerkarena properti yang diperbarui dapat diganti dengan nilai yang dikirimkan selama UPDATE_MODEL_VALUESfase berikutnya . Itulah mengapa Anda melihat di aplikasi / tutorial / sumber JSF 1.x lama bahwa a valueChangeListenerdalam konstruksi seperti itu telah digunakan dalam kombinasi dengan immediate="true"dan FacesContext#renderResponse()untuk mencegah hal itu terjadi. Bagaimanapun, menggunakan valueChangeListeneruntuk mengeksekusi tindakan bisnis sebenarnya selalu merupakan peretasan / solusi.
Diringkas: Gunakan valueChangeListenerhanya jika Anda perlu menghentikan perubahan nilai aktual itu sendiri. Yaitu Anda benar-benar tertarik baik yang lama dan nilai baru (misalnya untuk login mereka).
public void changeListener(ValueChangeEvent event) {
changeLogger.log(event.getOldValue(), event.getNewValue());
}
Gunakan <f:ajax listener>hanya jika Anda perlu melakukan tindakan bisnis pada nilai yang baru diubah. Yaitu Anda sebenarnya hanya tertarik pada nilai baru (misalnya untuk mengisi dropdown kedua).
public void ajaxListener(AjaxBehaviorEvent event) {
selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}
Jika Anda sebenarnya juga tertarik dengan nilai lama saat menjalankan tindakan bisnis, kembali ke valueChangeListener, tetapi antrekan ke INVOKE_APPLICATIONfase.
public void changeListener(ValueChangeEvent event) {
if (event.getPhaseId() != PhaseId.INVOKE_APPLICATION) {
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
event.queue();
return;
}
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
System.out.println(newValue.equals(value));
}
logger.trace( "setting changeTypes from {} to {}", this.changeTypes, changeTypes );. Sepertinya Anda dapat menggunakan nilai lama dan baru yang diperoleh dengan cara itu untuk melakukan logika bisnis secara langsung di setter serta logging sederhana, tetapi saya tidak tahu apakah ini akan menyebabkan efek samping ...