Pregunta ¿Cuándo usar valueChangeListener o f: ajax listener?


¿Cuál es la diferencia entre los siguientes dos códigos - en lo que respecta a listener ¿colocación?

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

y

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

73
2017-08-09 08:05


origen


Respuestas:


los valueChangeListener solo se invocará cuando se envíe el formulario y el valor presentado es diferente del valor inicial. Por lo tanto, no se invoca cuando solamente el DOM HTML change evento es despedido Si desea enviar el formulario durante el DOM HTML change evento, entonces necesitarías 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 usas <f:ajax listener> en lugar de valueChangeListener, se ejecutaría por defecto durante el DOM HTML change evento ya. Dentro UICommand componentes y componentes de entrada que representan una casilla de verificación o un botón de radio, sería ejecutado por defecto durante el DOM HTML click evento solo

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

Otra gran diferencia es que valueChangeListener método se invoca al final de la PROCESS_VALIDATIONS fase. En ese momento, el valor enviado aún no se ha actualizado en el modelo. Entonces no puede obtenerlo simplemente accediendo a la propiedad de bean que está vinculada a los componentes de entrada value. Tienes que conseguirlo por ValueChangeEvent#getNewValue(). Por cierto, el valor anterior también está disponible por ValueChangeEvent#getOldValue().

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

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

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 otro propiedad basada en el valor enviado, entonces fallará cuando esté usando valueChangeListener como la propiedad actualizada poder ser anulado por el valor presentado durante la siguiente UPDATE_MODEL_VALUES fase. Es exactamente por eso que se ve en las antiguas aplicaciones JSF 1.x / tutoriales / recursos que una valueChangeListener está en tal construcción se ha utilizado en combinación con immediate="true" y FacesContext#renderResponse() para evitar que eso suceda. Después de todo, usando el valueChangeListener ejecutar acciones comerciales en realidad siempre ha sido un truco / solución.

Resumido: use el valueChangeListener solo si necesita interceptar el cambio de valor real. Es decir. en realidad estás interesado en ambos el valor antiguo y el nuevo (por ejemplo, para registrarlos).

public void changeListener(ValueChangeEvent event) {
    changeLogger.log(event.getOldValue(), event.getNewValue());
}

Utilizar el <f:ajax listener> solo si necesita ejecutar una acción comercial sobre el valor recientemente cambiado. Es decir. en realidad estás interesado en solamente el nuevo valor (por ejemplo, llenar 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, entonces retroceda a valueChangeListener, pero ponlo en cola 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)); // true
    // ...
}

158
2017-08-09 12:02



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 esto respuesta práctica


7
2017-08-09 08:20