Le valueChangeListenerne sera invoqué que lorsque le formulaire est soumis et que la valeur soumise est différente de la valeur initiale. Il n'est donc pas appelé lorsque seul l' changeévénement HTML DOM est déclenché. Si vous souhaitez soumettre le formulaire pendant l' changeévénement HTML DOM , vous devez en ajouter un autre <f:ajax/>sans écouteur (!) Au composant d'entrée. Cela entraînera une soumission de formulaire qui ne traite que le composant actuel (comme dans execute="@this").
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
Lors de l'utilisation <f:ajax listener>au lieu de valueChangeListener, il serait déjà exécuté par défaut lors de l' changeévénement HTML DOM . À l'intérieur des UICommandcomposants et des composants d'entrée représentant une case à cocher ou un radiobutton, il serait par défaut exécuté pendant l' clickévénement HTML DOM uniquement.
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
Une autre différence majeure est que la valueChangeListenerméthode est appelée à la fin de la PROCESS_VALIDATIONSphase. À ce moment, la valeur soumise n'est pas encore mise à jour dans le modèle. Vous ne pouvez donc pas l'obtenir en accédant simplement à la propriété du bean qui est liée au composant d'entrée value. Vous devez y arriver ValueChangeEvent#getNewValue(). L'ancienne valeur est d'ailleurs également disponible par ValueChangeEvent#getOldValue().
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
}
La <f:ajax listener>méthode est appelée pendant la INVOKE_APPLICATIONphase. À ce moment, la valeur soumise est déjà mise à jour dans le modèle. Vous pouvez simplement l'obtenir en accédant directement à la propriété du bean qui est liée au composant d'entrée value.
private Object value;
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value);
}
De plus, si vous devez mettre à jour une autre propriété en fonction de la valeur soumise, elle échouera lorsque vous l'utilisez, valueChangeListenercar la propriété mise à jour peut être remplacée par la valeur soumise lors de la UPDATE_MODEL_VALUESphase suivante . C'est exactement pourquoi vous voyez dans les anciennes applications / tutoriels / ressources JSF 1.x qu'un valueChangeListenerest dans une telle construction a été utilisé en combinaison avec immediate="true"et FacesContext#renderResponse()pour empêcher que cela se produise. Après tout, l'utilisation de valueChangeListenerpour exécuter des actions commerciales a toujours été un hack / une solution de contournement.
Résumé: utilisez le valueChangeListeneruniquement si vous devez intercepter le changement de valeur réelle lui-même. -À- dire que vous êtes réellement intéressé à la fois l'ancienne et la nouvelle valeur (par exemple pour les log).
public void changeListener(ValueChangeEvent event) {
changeLogger.log(event.getOldValue(), event.getNewValue());
}
Utilisez le <f:ajax listener>uniquement si vous devez exécuter une action commerciale sur la valeur nouvellement modifiée. C'est-à-dire que vous n'êtes réellement intéressé que par la nouvelle valeur (par exemple pour remplir une deuxième liste déroulante).
public void ajaxListener(AjaxBehaviorEvent event) {
selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}
Si vous êtes également intéressé par l'ancienne valeur lors de l'exécution d'une action commerciale, revenez valueChangeListenerà la INVOKE_APPLICATIONphase , mais mettez-la en file d'attente .
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 );. Il semble que vous puissiez utiliser les anciennes et les nouvelles valeurs obtenues de cette manière pour faire de la logique métier directement dans le setter ainsi qu'une simple journalisation, mais je ne sais pas si cela provoquerait des effets secondaires ...