valueChangeListener
Sadece 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 change
olayı tetiklendiğinde çağrılmaz . HTML DOM change
etkinliğ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 change
zaten HTML DOM etkinliği sırasında yürütülür . İçinde UICommand
bileşenleri ve bir onay kutusu veya RadioButton temsil girdi bileşenleri, HTML DOM sırasında çalıştırılan varsayılan olarak olurdu click
sadece olayın.
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
Diğer bir önemli fark, valueChangeListener
yöntemin PROCESS_VALIDATIONS
aş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_APPLICATION
faz. 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 valueChangeListener
güncellenmiş özellik olarak yapabilirsiniz müteakip sırasında gönderilen değerin geçersiz kılınabilir UPDATE_MODEL_VALUES
fazı. İşte tam da bu yüzden eski JSF 1.x uygulamalarında / öğreticilerinde / kaynaklarında a'nın valueChangeListener
bö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, valueChangeListener
iş eylemlerini yürütmek için kullanmak aslında her zaman bir hack / geçici çözüm olmuştur.
Özetle: valueChangeListener
Gerç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_APPLICATION
aş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 ...