valueChangeListener
Zostanie wywołany tylko wtedy, gdy formularz jest składany i przedłożone wartość różni się od wartości początkowej. Dlatego nie jest wywoływana, gdy uruchamiane jest tylkochange
zdarzenie HTML DOM . Jeśli chcesz wysłać formularz podczas change
zdarzenia HTML DOM , musisz dodać kolejny <f:ajax/>
bez listenera (!) Do komponentu wejściowego. Spowoduje to przesłanie formularza, który przetwarza tylko bieżący komponent (jak w execute="@this"
).
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
W przypadku użycia <f:ajax listener>
zamiast valueChangeListener
, byłoby to domyślnie wykonywane już podczas change
zdarzenia HTML DOM . Wewnątrz UICommand
komponentów i komponentów wejściowych reprezentujących pole wyboru lub radiobutton byłby on domyślnie wykonywany tylko podczas click
zdarzenia HTML DOM .
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
Inną istotną różnicą jest to, że valueChangeListener
metoda jest wywoływana pod koniec PROCESS_VALIDATIONS
fazy. W tym momencie podana wartość nie jest jeszcze aktualizowana w modelu. Więc nie możesz tego uzyskać, po prostu uzyskując dostęp do właściwości bean, która jest powiązana z komponentem wejściowym value
. Musisz to zrobić ValueChangeEvent#getNewValue()
. Nawiasem mówiąc, stara wartość jest również dostępna przez ValueChangeEvent#getOldValue()
.
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
}
<f:ajax listener>
Sposób wywoływany jest w INVOKE_APPLICATION
fazie. W tym momencie przesłana wartość jest już zaktualizowana w modelu. Możesz go po prostu uzyskać, uzyskując bezpośredni dostęp do właściwości bean, która jest powiązana ze składnikiem wejściowym value
.
private Object value;
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value);
}
Ponadto, jeśli musisz zaktualizować inną właściwość na podstawie przesłanej wartości, to zakończy się niepowodzeniem, gdy używasz valueChangeListener
zaktualizowanej właściwości, która może zostać zastąpiona przez przesłaną wartość w kolejnej UPDATE_MODEL_VALUES
fazie. Właśnie dlatego widzisz w starych aplikacjach / samouczkach / zasobach JSF 1.x, że element a valueChangeListener
jest w takiej konstrukcji został użyty w połączeniu z immediate="true"
i FacesContext#renderResponse()
aby temu zapobiec. W końcu korzystanie z narzędzia valueChangeListener
do wykonywania działań biznesowych zawsze było włamaniem / obejściem.
Podsumowanie: użyj valueChangeListener
tylko wtedy, gdy musisz przechwycić samą zmianę wartości. Oznacza to, że jesteś zainteresowany zarówno starą, jak i nową wartością (np. Aby je zarejestrować).
public void changeListener(ValueChangeEvent event) {
changeLogger.log(event.getOldValue(), event.getNewValue());
}
Użyj <f:ajax listener>
tylko, jeśli musisz wykonać akcję biznesową na nowo zmienionej wartości. Oznacza to, że interesuje Cię tylko nowa wartość (np. Aby wypełnić drugie menu).
public void ajaxListener(AjaxBehaviorEvent event) {
selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}
Jeśli faktycznie interesuje Cię stara wartość podczas wykonywania czynności biznesowej, wróć do valueChangeListener
, ale ustaw ją w kolejce do INVOKE_APPLICATION
fazy.
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 );
. Wygląda na to, że można by wykorzystać stare i nowe wartości uzyskane w ten sposób do wykonywania logiki biznesowej bezpośrednio w ustawiaczu, a także do prostego logowania, ale nie wiem, czy to spowodowałoby skutki uboczne ...dla pierwszego fragmentu (atrybut AJAX listener):
Atrybut „listener” tagu Ajax jest metodą wywoływaną po stronie serwera za każdym razem, gdy funkcja AJAX ma miejsce po stronie klienta. Na przykład, możesz użyć tego atrybutu, aby określić funkcję po stronie serwera, która ma być wywoływana za każdym razem, gdy użytkownik naciśnie klawisz
ale drugi fragment (valueChangeListener):
Element ValueChangeListener zostanie wywołany tylko po przesłaniu formularza, a nie po zmianie wartości danych wejściowych
* możesz chcieć zobaczyć tę przydatną odpowiedź
źródło