El valueChangeListener
sólo se invoca cuando se envía el formulario y el valor presentado es diferente del valor inicial. Por lo tanto, no se invoca cuando solo se activa el change
evento DOM de HTML . Si desea enviar el formulario durante el change
evento DOM de HTML , deberá agregar otro <f:ajax/>
sin un oyente (!) Al componente de entrada. Causará un envío de formulario que procesa solo el componente actual (como en execute="@this"
).
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
Cuando se usa en <f:ajax listener>
lugar de valueChangeListener
, ya se ejecutará de forma predeterminada durante el change
evento DOM de HTML . Dentro de los UICommand
componentes y los componentes de entrada que representan una casilla de verificación o un botón de radio, se ejecutará de forma predeterminada solo durante el click
evento DOM de HTML .
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
Otra diferencia importante es que el valueChangeListener
método se invoca durante el final de la PROCESS_VALIDATIONS
fase. En ese momento, el valor enviado aún no se ha actualizado en el modelo. Por lo tanto, no puede obtenerlo simplemente accediendo a la propiedad del bean que está vinculada al componente de entrada value
. Tienes que conseguirlo ValueChangeEvent#getNewValue()
. Por cierto, el valor antiguo también está disponible por ValueChangeEvent#getOldValue()
.
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
}
El <f:ajax listener>
método se invoca durante la INVOKE_APPLICATION
fase. En ese momento, el valor enviado ya está actualizado en el modelo. Puede obtenerlo accediendo directamente a la propiedad del bean que está vinculada al componente de entrada value
.
private Object value;
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value);
}
Además, si necesita actualizar otra propiedad en función del valor enviado, fallará cuando esté utilizando, valueChangeListener
ya que la propiedad actualizada puede ser anulada por el valor enviado durante la UPDATE_MODEL_VALUES
fase siguiente . Esa es exactamente la razón por la que ve en las aplicaciones / tutoriales / recursos antiguos de JSF 1.x que valueChangeListener
se ha usado un en tal construcción en combinación con immediate="true"
y FacesContext#renderResponse()
para evitar que eso suceda. Después de todo, usando elvalueChangeListener
para ejecutar acciones comerciales siempre ha sido un truco / solución alternativa.
Resumido: use el valueChangeListener
solo si necesita interceptar el cambio de valor real. Es decir, está realmente interesado tanto en el valor antiguo como en el nuevo (por ejemplo, para registrarlos).
public void changeListener(ValueChangeEvent event) {
changeLogger.log(event.getOldValue(), event.getNewValue());
}
Use el <f:ajax listener>
solo si necesita ejecutar una acción comercial sobre el valor recién cambiado. Es decir, en realidad está interesado solo en el nuevo valor (por ejemplo, para completar un segundo menú desplegable).
public void ajaxListener(AjaxBehaviorEvent event) {
selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}
Si en realidad también está interesado en el valor anterior mientras ejecuta una acción comercial, retroceda valueChangeListener
, pero colóquelo en la INVOKE_APPLICATION
fase.
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 );
. Parece que podría usar los valores antiguos y nuevos obtenidos de esa manera para hacer la lógica comercial directamente en el establecedor, así como para un registro simple, pero no sé si esto causaría efectos secundarios ...