webentwicklung-frage-antwort-db.com.de

Wann sollte valueChangeListener oder f: ajax Listener verwendet werden?

Was ist der Unterschied zwischen den folgenden beiden Codeteilen - in Bezug auf die Platzierung von listener?

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

und

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

Das valueChangeListener wird nur aufgerufen, wenn das Formular gesendet wird nd der gesendete Wert weicht vom ursprünglichen Wert ab. Es wird daher nicht aufgerufen, wenn only das HTML DOM change -Ereignis ausgelöst wird. Wenn Sie das Formular während des HTML DOM change -Ereignisses senden möchten, müssen Sie der Eingabekomponente ein weiteres <f:ajax/> Ohne Listener (!) Hinzufügen. Dadurch wird ein Formular gesendet, das nur die aktuelle Komponente verarbeitet (wie in execute="@this").

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

Wenn Sie <f:ajax listener> Anstelle von valueChangeListener verwenden, wird dies standardmäßig bereits während des Ereignisses HTML DOM change ausgeführt. Innerhalb von UICommand -Komponenten und Eingabekomponenten, die ein Kontrollkästchen oder einen Radiobutton darstellen, wird dies standardmäßig nur während des HTML-DOM-Ereignisses click ausgeführt.

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

Ein weiterer wesentlicher Unterschied besteht darin, dass die valueChangeListener -Methode am Ende der PROCESS_VALIDATIONS - Phase aufgerufen wird. Zu diesem Zeitpunkt wurde der übermittelte Wert im Modell noch nicht aktualisiert. Sie können es also nicht erhalten, indem Sie einfach auf die Bean-Eigenschaft zugreifen, die an das value der Eingabekomponente gebunden ist. Sie müssen es mit ValueChangeEvent#getNewValue() abrufen. Der alte Wert ist übrigens auch über ValueChangeEvent#getOldValue() verfügbar.

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

Die Methode <f:ajax listener> Wird während der Phase INVOKE_APPLICATION Aufgerufen. Zu diesem Zeitpunkt wurde der übermittelte Wert bereits im Modell aktualisiert. Sie können es einfach abrufen, indem Sie direkt auf die Bean-Eigenschaft zugreifen, die an das value der Eingabekomponente gebunden ist.

private Object value; // +getter+setter.

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

Wenn Sie außerdem die Eigenschaft another basierend auf dem übergebenen Wert aktualisieren müssen, schlägt dies fehl, wenn Sie valueChangeListener als aktualisierte Eigenschaft can in der nachfolgenden Phase UPDATE_MODEL_VALUES vom übergebenen Wert überschrieben werden. Genau deshalb sehen Sie in alten JSF 1.x-Anwendungen/Tutorials/Ressourcen, dass ein valueChangeListener in einem solchen Konstrukt in Kombination mit immediate="true" Und FacesContext#renderResponse() verwendet wurde, um dies zu verhindern vom Geschehen. Schließlich war die Verwendung von valueChangeListener zum Ausführen von Geschäftsaktionen immer ein Hack/Workaround.

Zusammengefasst: Verwenden Sie valueChangeListener nur, wenn Sie die tatsächliche Wertänderung selbst abfangen müssen. Das heißt Sie interessieren sich tatsächlich für beides den alten und den neuen Wert (z. B. um sie zu protokollieren).

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

Verwenden Sie den <f:ajax listener> Nur, wenn Sie eine Geschäftsaktion für den neu geänderten Wert ausführen müssen. Das heißt Sie interessieren sich tatsächlich für only den neuen Wert (z. B. um ein zweites Dropdown-Feld auszufüllen).

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

Wenn Sie während der Ausführung einer Geschäftsaktion auch an dem alten Wert interessiert sind, greifen Sie auf valueChangeListener zurück, stellen Sie ihn jedoch in die Phase INVOKE_APPLICATION Ein.

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
    // ...
}
177
BalusC

für das erste Fragment (Ajax-Listener-Attribut):

Das Attribut "Listener" eines Ajax-Tags ist eine Methode, die auf der Serverseite jedes Mal aufgerufen wird, wenn die Ajax-Funktion auf der Clientseite ausgeführt wird. Sie können dieses Attribut beispielsweise verwenden, um eine serverseitige Funktion anzugeben, die jedes Mal aufgerufen wird, wenn der Benutzer eine Taste drückt

aber das zweite Fragment (valueChangeListener):

Der ValueChangeListener wird nur aufgerufen, wenn das Formular gesendet wird, nicht, wenn der Wert der Eingabe geändert wird

* Vielleicht möchten Sie dies anzeigen handliche Antwort

9
a.u.r