90

listener配置に関して、次の2つのコードの違いは何ですか?

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

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

2 に答える 2

187

は、フォームが送信さ、送信された値が初期値と異なるvalueChangeListener場合にのみ呼び出されます。したがって、HTMLDOMイベントのみが発生した場合は呼び出されません。HTML DOMイベント中にフォームを送信する場合は、リスナー(!)なしで別のフォームを入力コンポーネントに追加する必要があります。これにより、現在のコンポーネントのみを処理するフォーム送信が発生します(のように)。changechange<f:ajax/>execute="@this"

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

<f:ajax listener>の代わりに使用する場合valueChangeListener、デフォルトでは、HTMLDOMchangeイベント中にすでに実行されます。チェックボックスまたはラジオボタンを表すコンポーネントおよび入力コンポーネントの内部UICommandでは、デフォルトではHTMLDOMclickイベント中にのみ実行されます。

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

もう1つの大きな違いは、フェーズvalueChangeListenerの終了時にメソッドが呼び出されることです。PROCESS_VALIDATIONSその時点では、送信された値はモデルでまだ更新されていません。したがって、入力コンポーネントのにバインドされているbeanプロパティにアクセスするだけでは取得できませんvalue。で取得する必要がありますValueChangeEvent#getNewValue()。ちなみに、古い値はによっても利用できますValueChangeEvent#getOldValue()

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

メソッドはフェーズ<f:ajax listener>中に呼び出されます。INVOKE_APPLICATIONその時点で、送信された値はモデルですでに更新されています。入力コンポーネントのにバインドされているbeanプロパティに直接アクセスすることで取得できますvalue

private Object value; // +getter+setter.

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

また、送信された値に基づいて別のプロパティを更新する必要がある場合は、使用中に失敗します。これはvalueChangeListener、更新されたプロパティが後続のフェーズで送信された値によって上書きされる可能性があるためです。UPDATE_MODEL_VALUESそのため、古いJSF 1.xアプリケーション/チュートリアル/リソースで、avalueChangeListenerがそのような構成に含まれていることが、それと組み合わせて使用​​され、immediate="true"それFacesContext#renderResponse()が発生しないようになっていることがわかります。結局のところ、valueChangeListenerビジネスアクションを実行するためにを使用することは、実際には常にハック/回避策でした。

要約:valueChangeListener実際の値の変更自体を傍受する必要がある場合にのみ使用してください。つまり、実際には古い値と新しい値の両方に関心があります(たとえば、それらをログに記録するため)。

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

<f:ajax listener>新しく変更された値に対してビジネスアクションを実行する必要がある場合にのみ使用してください。つまり、実際には新しい値のみに関心があります(たとえば、2番目のドロップダウンにデータを入力するため)。

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

ビジネスアクションの実行中に古い値にも実際に関心がある場合は、にフォールバックしますが、フェーズvalueChangeListenerにキューイングします。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
    // ...
}
于 2012-08-09T12:02:13.010 に答える
9

最初のフラグメント(ajaxリスナー属性)の場合:

ajaxタグの「listener」属性は、ajax関数がクライアント側で発生するたびにサーバー側で呼び出されるメソッドです。たとえば、この属性を使用して、ユーザーがキーを押すたびに呼び出すサーバー側関数を指定できます。

しかし、2番目のフラグメント(valueChangeListener):

ValueChangeListenerは、入力の値が変更されたときではなく、フォームが送信されたときにのみ呼び出されます

*あなたはこの便利な答えを見たいかもしれません

于 2012-08-09T08:20:14.903 に答える