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