web-dev-qa-db-ja.com

すべきでないときに入力をスキップする「immediate = "true"」を理解しようとする

すぐに理解したと思ったとき...

次のJSFページを検討してください。

_<h:inputText value="#{testBean.text}" required="true" />
<h:commandButton actionListener="#{testBean.doFoo}" value="Do Foo" />
<h:commandButton immediate="true" actionListener="#{testBean.doBar}" value="Do Bar" /><br />
<h:outputText value="#{testBean.didSomething}" />
_

そして、このバッキングBean:

_public class TestBean {
   private String didSomething = "Nothing done yet";
   // + getter

public void doFoo() {
    didSomething = "Did foo!";        
}

public void doBar() {
    didSomething = "Did bar!";        
}
_

私は即時について読んだすべてから、私は次を期待するでしょう:

  • 入力フィールドに値を指定せずにfooを実行しようとすると、processValidationsPhaseの間にエラーが発生し、このフェーズの直後にページがエラーメッセージで再レンダリングされるため、アクションは実行されません。 didSomethingの値は変更されません。 (これは期待どおりに機能します)

  • 入力フィールドに値を指定せずにbarを実行しようとすると、即時属性のため、アクションはapplyRequestValuesPhaseの間に実行されます。変数didSomethingが変更されます。 (これは期待どおりに機能します)

次に何が起こるか、 この説明 状態:

「アクションメソッドの結果としてのnull戻り値により、処理は通常どおり続行されます。つまり、非即時コンポーネントが検証され、更新モデルが実行されます(検証エラーが発生しなかった場合)。voidを返すアクションリスナーメソッドの場合、通常のフローが望ましくない場合は、facesContext.renderResponse()を呼び出す必要があります。」

このことから、処理が通常どおり続行するという考えがありました(アクションメソッドが結果を返さず、renderResponse()を強制しないため)、同じ検証エラーが発生します。唯一の違いは、didSomethingを設定した後でafterが発生することです。 ただし、これは起こりません。代わりに、入力フィールドに触れずに、サイトが残りのフェーズをすべてスキップしているように感じます。エラーメッセージなしで再レンダリングします。

これがどのように機能するかについての私の理解が間違っている場所を誰かに説明できますか?

22
Louise

ボタンにimmediate="true"を指定すると、アクションは要求値の適用フェーズ中に実際に呼び出され、残りのすべてのフェーズはスキップされます。これは、この属性の唯一のポイントでもあります。要求値の適用フェーズでコンポーネントをすぐに処理(デコード、検証、更新、呼び出し)します。

notimmediate="true"を持つ入力はすべて無視されます。 immediate="true"を持つ入力のみも処理されますが、これは要求値の適用フェーズでも発生します。要求値の適用フェーズですべてがすでに行われている場合、残りのフェーズを呼び出す必要があるのはなぜですか?

デバッグJSFライフサイクル の記事では、immediate"true"を使用する(使用しない)タイミングを明らかにする必要がある次の要約を見つけることができます。

さて、immediate属性をいつ使用する必要がありますか?

まだ完全に明確でない場合、以下に要約を示します。有益な場合には、実際の使用例を示します。

  • UIInput(s)のみに設定されている場合、プロセス検証フェーズは代わりに要求値の適用フェーズで実行されます。これを使用して、問題のUIInputコンポーネントの検証に優先順位を付けます。それらのいずれかで検証/変換が失敗すると、非即時コンポーネントは検証/変換されません。

  • UICommandのみで設定されている場合、UIInputコンポーネントのいずれかでモデル値の更新フェーズがスキップされるまで、要求値の適用フェーズはスキップされます。これを使用して、フォームの処理全体をスキップします。例えば。 「キャンセル」または「戻る」ボタン。

  • UIInputコンポーネントとUICommandコンポーネントの両方で設定されている場合、モデル値の更新フェーズがあるまで、要求値の適用フェーズは、そうでないUIInputコンポーネントのいずれかでスキップされます。この属性が設定されています。これを使用して、特定のフィールド(即時)に必要なフォーム全体の処理をスキップします。例えば。必須ではあるが非即時のパスワードフィールドがあるログインフォームの[パスワードを忘れた]ボタン。

こちらもご覧ください:

37
BalusC