valueChangeListenerSadece form gönderildiğinde çağrılır ve gönderilen değer başlangıç değerinden farklıdır. Bu nedenle, yalnızca HTML DOM changeolayı tetiklendiğinde çağrılmaz . HTML DOM changeetkinliği sırasında formu göndermek isterseniz <f:ajax/>, giriş bileşenine dinleyici (!) Olmadan başka bir form eklemeniz gerekir . Yalnızca mevcut bileşeni (olduğu gibi execute="@this") işleyen bir form gönderilmesine neden olur .
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
<f:ajax listener>Bunun yerine kullanıldığında valueChangeListener, varsayılan olarak changezaten HTML DOM etkinliği sırasında yürütülür . İçinde UICommandbileşenleri ve bir onay kutusu veya RadioButton temsil girdi bileşenleri, HTML DOM sırasında çalıştırılan varsayılan olarak olurdu clicksadece olayın.
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
Diğer bir önemli fark, valueChangeListeneryöntemin PROCESS_VALIDATIONSaşamanın sonunda devreye girmesidir . O anda, gönderilen değer modelde henüz güncellenmemiştir. Dolayısıyla, giriş bileşenine bağlı olan bean özelliğine erişerek bunu elde edemezsiniz value. Bunu almalısın ValueChangeEvent#getNewValue(). Bu arada eski değer de mevcuttur ValueChangeEvent#getOldValue().
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
}
<f:ajax listener>Yöntem sırasında çağrılan INVOKE_APPLICATIONfaz. O anda, sunulan değer modelde zaten güncellenmiştir. Girdi bileşenine bağlı olan bean özelliğine doğrudan erişerek bunu elde edebilirsiniz value.
private Object value;
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value);
}
Güncelleştirmek gerekir Ayrıca, başka gönderilen değerine dayalı mülkiyet, o zaman kullandığınız zaman başarısız olur valueChangeListenergüncellenmiş özellik olarak yapabilirsiniz müteakip sırasında gönderilen değerin geçersiz kılınabilir UPDATE_MODEL_VALUESfazı. İşte tam da bu yüzden eski JSF 1.x uygulamalarında / öğreticilerinde / kaynaklarında a'nın valueChangeListenerböyle bir yapıda olduğunu immediate="true"ve bunun FacesContext#renderResponse()olmasını önlemek için birlikte kullanıldığını görüyorsunuz . Sonuçta, valueChangeListeneriş eylemlerini yürütmek için kullanmak aslında her zaman bir hack / geçici çözüm olmuştur.
Özetle: valueChangeListenerGerçek değer değişikliğinin kendisine müdahale etmeniz gerekiyorsa yalnızca kullanın . Yani aslında hem eski hem de yeni değerle ilgileniyorsunuz (örneğin bunları kaydetmek için).
public void changeListener(ValueChangeEvent event) {
changeLogger.log(event.getOldValue(), event.getNewValue());
}
Kullanın <f:ajax listener>Eğer yeni değiştirdiğiniz değeri üzerinde bir iş işlemi çalıştırmak için gereken yalnızca. Yani aslında yalnızca yeni değerle ilgileniyorsunuz (örneğin, ikinci bir açılır menüyü doldurmak için).
public void ajaxListener(AjaxBehaviorEvent event) {
selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}
Bir ticari eylemi gerçekleştirirken aslında eski değerle de ilgileniyorsanız, o zaman geri dönün valueChangeListener, ancak INVOKE_APPLICATIONaşamada sıraya koyun .
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 );. Bu şekilde elde edilen eski ve yeni değerleri doğrudan ayarlayıcıda iş mantığı ve basit günlük kaydı yapmak için kullanabilirsiniz gibi görünüyor , ancak bunun yan etkilere neden olup olmayacağını bilmiyorum ...