valueChangeListener
フォームが送信された場合にのみ呼び出されると、送信された値が初期値と異なっています。したがって、HTMLDOMイベントのみが発生した場合は呼び出されませんchange
。HTML DOMchange
イベント中にフォームを送信する場合は<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;
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value);
}
また、送信された値に基づいて別のプロパティを更新する必要がある場合は、使用中に失敗します。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));
}
logger.trace( "setting changeTypes from {} to {}", this.changeTypes, changeTypes );