inputtext example ajax jsf jsf-2 listener valuechangelistener

ajax - example - valuechangelistener picklist primefaces



¿Cuándo usar valueChangeListener o f: ajax listener? (2)

¿Cuál es la diferencia entre los siguientes dos códigos: con respecto a la ubicación del listener ?

<h:selectOneMenu ...> <f:selectItems ... /> <f:ajax listener="#{bean.listener}" /> </h:selectOneMenu>

y

<h:selectOneMenu ... valueChangeListener="#{bean.listener}"> <f:selectItems ... /> </h:selectOneMenu>


para el primer fragmento (atributo de oyente ajax):

El atributo "oyente" de una etiqueta ajax es un método que se llama en el lado del servidor cada vez que la función ajax ocurre en el lado del cliente. Por ejemplo, puede usar este atributo para especificar una función del lado del servidor para llamar cada vez que el usuario presiona una tecla

pero el segundo fragmento (valueChangeListener):

El ValueChangeListener solo se invocará cuando se envíe el formulario, no cuando se cambie el valor de la entrada

* es posible que desee ver esta útil respuesta


valueChangeListener solo se invocará cuando se valueChangeListener el formulario y el valor enviado sea diferente del valor inicial. Por lo tanto, no se invoca cuando solo se activa el evento de change HTML DOM. Si desea enviar el formulario durante el evento de change HTML DOM, entonces 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 <f:ajax listener> lugar de valueChangeListener , se ejecutaría de manera predeterminada durante el evento HTML DOM change event. Dentro de los componentes de UICommand y los componentes de entrada que representan una casilla de verificación o un UICommand , se ejecutarán por defecto solo durante el evento de click HTML DOM.

<h:selectOneMenu value="#{bean.value}"> <f:selectItems ... /> <f:ajax listener="#{bean.ajaxListener}" /> </h:selectOneMenu>

Otra diferencia importante es que el método valueChangeListener se invoca al final de la fase PROCESS_VALIDATIONS . 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 Bean que está vinculada al value del componente de entrada. ValueChangeEvent#getNewValue() obtenerlo por ValueChangeEvent#getNewValue() . El valor anterior también está disponible por ValueChangeEvent#getOldValue() .

public void changeListener(ValueChangeEvent event) { Object oldValue = event.getOldValue(); Object newValue = event.getNewValue(); // ... }

El método <f:ajax listener> se invoca durante la fase INVOKE_APPLICATION . En ese momento, el valor enviado ya se ha actualizado en el modelo. Puede obtenerlo accediendo directamente a la propiedad del bean que está vinculada al value del componente de entrada.

private Object value; // +getter+setter. public void ajaxListener(AjaxBehaviorEvent event) { System.out.println(value); // Look, (new) value is already set. }

Además, si necesita actualizar otra propiedad en función del valor enviado, fallaría cuando use valueChangeListener ya que la propiedad actualizada puede anularse por el valor enviado durante la siguiente fase UPDATE_MODEL_VALUES . Es exactamente por eso que se ve en aplicaciones / tutoriales / recursos antiguos de JSF 1.x que un valueChangeListener está en tal construcción usado en combinación con immediate="true" y FacesContext#renderResponse() para evitar que eso ocurra. Después de todo, el uso de valueChangeListener para ejecutar acciones comerciales en realidad siempre ha sido un truco / solución.

Resumido: utilice valueChangeListener solo si necesita interceptar el cambio de valor real. Es decir, en realidad está 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 <f:ajax listener> solo si necesita ejecutar una acción comercial sobre el valor recientemente cambiado. Es decir, en realidad solo está interesado en el nuevo valor (por ejemplo, para completar un segundo menú desplegable).

public void ajaxListener(AjaxBehaviorEvent event) { selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown); }

Si también está interesado en el valor anterior mientras ejecuta una acción comercial, vuelva a valueChangeListener , pero INVOKE_APPLICATION fase INVOKE_APPLICATION .

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)); // true // ... }