26

すぐにわかったと思ったら…(はぁ)

次の 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、immediate 属性のためにアクションが実行されます。変数didSomethingが変更されます。(これは期待どおりに動作します)

次に何が起こるかについて、この説明は次のように述べています。

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

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

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

4

1 に答える 1

45

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

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

デバッグ JSF ライフサイクルの記事では、次の要約を見つけることができますimmediate"true"

では、immediate 属性はいつ使用すればよいでしょうか。

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

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

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

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

以下も参照してください。

于 2012-10-18T18:19:48.670 に答える