3

ビュースコープのBeanを使用して頭を包み込もうとしています。私の投稿の長さを許してください。ビューがあります: page1.xhtml は、フォームを送信する Bean と commandButton を使用し、action 属性を介して同じ Bean のメソッドを呼び出します。

メソッドの戻り値により、ナビゲーション ルールが page2.xhtml に「移動」します。したがって、page1.xhtml で使用される「player」という名前の Bean は、ナビゲーションが page2.xhtml へのリクエスト フローを取得すると範囲外になることを理解しています。結局、各ビューは「player」という名前のビュー スコープ Bean を使用します。id という名前のパラメーターを伝える必要があります。したがって、page1.xhtml には、page1 を「送信」するために使用される commandButton の子要素として要素があります。

page2.xhtml は、page2.xhtml のレンダリングの前にビュー スコープ Bean をロードする必要があるため、次の構成を使用します。

<ui:define name="metadata">
   <f:metadata>
     <f:viewParam name="id" value="#{player.id}" />
    <!--  this should cause bean to be loaded before it's needed for initial rendering -->
    <f:event type="preRenderView" listener="#{player.initFromId}"/>
  </f:metadata>
</ui:define>

player.initFromId メソッドでは、FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); によって返されたマップのキーと値を stdout にダンプします。

何が見えますか?[クライアントが保存したビュー ステートのほとんどをこのリストから削除しました :-)] ほとんどのキーは完全に修飾された UI コンポーネント名であり、期待どおりにコンポーネント階層の名前が付けられています。良い。典型的な POST nv ペア...

最後に私の質問: key: id があると仮定するのは正しいですか? 私はそう願っていますが、あまり仮定するのは好きではありません。ほとんどの場合、私はより深刻なトラブルに巻き込まれます。

ただし、f:viewParam では、preRenderView イベントを介して、player.initFromId() の前に player.setId() メソッドが呼び出されることはありません。player.initFromId() が呼び出されますが、セッターではありませんか??

別のビュー/ページ (この例では page2.xhtml) によって呼び出されるコードによって UI コンポーネントのフィールド名を使用することが設計目標であるとは想像できないので、私の仮定が正しいことを願っています。これでは、各ページの実装が密結合になり、外部化されたナビゲーション ルールは実質的に無意味になります。また、f:viewParam と f:param を使用する目的は、最小限の結合を提供することであると想定しています (宣言レベルでのみ - page1 は param を提供すると宣言し、page2 は param の必要性を宣言します - プロトコルはフレームワークに残されます)。 )。

Player.initFromId - key:id, value:37
Player.initFromId - key:javax.faces.ViewState, value:H4sIAAAAAA[....]YQfAAA=
Player.initFromId - key:javax.faces.partial.ajax, value:true
Player.initFromId - key:javax.faces.partial.execute, value:@all
Player.initFromId - key:javax.faces.partial.render, value:registrationForm:regPage
Player.initFromId - key:javax.faces.source, value:registrationForm:SubmitButton
Player.initFromId - key:registrationForm, value:registrationForm
Player.initFromId - key:registrationForm:SubmitButton, value:registrationForm:SubmitButton
Player.initFromId - key:registrationForm:firstName, value:Bob
Player.initFromId - key:registrationForm:j_idt18:carriers, value:Sprint
Player.initFromId - key:registrationForm:j_idt18:city, value:Sparta-test4
Player.initFromId - key:registrationForm:j_idt18:dob_input, value:
[ many other UI components key+value pairs omitted]

page1.xhtml から:

<p:commandButton tabindex="0" id="SubmitButton" value="Register" 
    action="#{player.register}" update="regPage" >
   <!--  this needs to be set after the register() method completes. is that so? -->
    <f:param name="id" value="#{player.id}"/>
</p:commandButton>

この過剰な投稿を読んでいただき、ありがとうございます。

4

1 に答える 1

1

あなたはフォワードでナビゲートしているようです。フォワードは基本的に、レンダリング レスポンス フェーズ中に新しいビューを作成します。転送されたリクエストでは実行され<f:viewParam>ません。最初のリクエストでのみ実行されます(最初にクライアントによって起動されたとおり)。クライアントが新しい GET リクエストを発行するように指示され、すべての<f:viewParam>作業がトリガーされるように、転送ではなくリダイレ​​クトでナビゲートする必要があります。faces-redirect=true次のようにナビゲーション結果にパラメーターを追加することで、それを実現できます。

return "page2?faces-redirect=true";

ただし、これにより、現在のリクエストのすべてのリクエスト パラメータが失われます。したがって、ナビゲーションの結果に明示的に追加する必要があります。

return "page2?faces-redirect=true&id=" + id;
于 2013-01-16T03:11:46.290 に答える