listener
の配置に関して、次の2つのコードの違いは何ですか?
<h:selectOneMenu ...>
<f:selectItems ... />
<f:ajax listener="#{bean.listener}" />
</h:selectOneMenu>
そして
<h:selectOneMenu ... valueChangeListener="#{bean.listener}">
<f:selectItems ... />
</h:selectOneMenu>
valueChangeListener
は、フォームが送信されたときにのみ呼び出されますおよび送信された値は初期値とは異なります。したがって、onlyHTML DOM change
イベントが発生したときは呼び出されません。 HTML DOM change
イベント中にフォームを送信する場合は、リスナー(!)なしで別の<f:ajax/>
を入力コンポーネントに追加する必要があります。現在のコンポーネントのみを処理するフォーム送信が行われます(execute="@this"
のように)。
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
valueChangeListener
の代わりに<f:ajax listener>
を使用する場合、デフォルトでは既にHTML DOM change
イベント中に実行されます。 UICommand
コンポーネントとチェックボックスまたはラジオボタンを表す入力コンポーネント内では、デフォルトでHTML DOM click
イベント中にのみ実行されます。
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
別の大きな違いは、valueChangeListener
メソッドがPROCESS_VALIDATIONS
フェーズの終了時に呼び出されることです。その時点では、送信された値はモデルでまだ更新されていません。したがって、入力コンポーネントのvalue
にバインドされているBeanプロパティにアクセスするだけでは取得できません。 ValueChangeEvent#getNewValue()
で取得する必要があります。古い値は、ValueChangeEvent#getOldValue()
でも利用可能です。
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
// ...
}
<f:ajax listener>
メソッドは、INVOKE_APPLICATION
フェーズ中に呼び出されます。その時点で、送信された値はすでにモデルで更新されています。入力コンポーネントのvalue
にバインドされているBeanプロパティに直接アクセスするだけで取得できます。
private Object value; // +getter+setter.
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value); // Look, (new) value is already set.
}
また、送信された値に基づいてanotherプロパティを更新する必要がある場合、valueChangeListener
を使用しているときに失敗します更新されたプロパティは、後続のUPDATE_MODEL_VALUES
フェーズ中に送信された値でオーバーライドできます。古いJSF 1.xアプリケーション/チュートリアル/リソースで、valueChangeListener
がimmediate="true"
およびFacesContext#renderResponse()
と組み合わせて使用され、そのような構成が使用されないのは、まさにそのためです。結局、valueChangeListener
を使用してビジネスアクションを実行することは、実際には常にハック/回避策でした。
要約:valueChangeListener
は、実際の値の変化自体を傍受する必要がある場合にのみ使用してください。つまり実際に興味があるのはboth古い値と新しい値です(例:それらを記録するため)。
public void changeListener(ValueChangeEvent event) {
changeLogger.log(event.getOldValue(), event.getNewValue());
}
<f:ajax listener>
は、新しく変更された値に対してビジネスアクションを実行する必要がある場合にのみ使用します。つまり実際に興味があるのは、新しい値にonlyだけです(たとえば、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
// ...
}
最初のフラグメント(ajaxリスナー属性):
Ajaxタグの「リスナー」属性は、クライアント側でajax関数が発生するたびにサーバー側で呼び出されるメソッドです。たとえば、この属性を使用して、ユーザーがキーを押すたびに呼び出すサーバー側関数を指定できます
しかし、2番目のフラグメント(valueChangeListener):
ValueChangeListenerは、入力の値が変更されたときではなく、フォームが送信されたときにのみ呼び出されます
*あなたはこれを見たいかもしれません 便利な答え