5

景色:

<h:form ...
  <p:dataTable value="#{myBean.list}" var="data" ...
     <p:column ...
        <h:commandButton action="#{controller.method(data.id)}" />
     </p:column>
  </p:dataTable>
</h:form>

コントローラー:

@ApplicationScoped
public class Controller {
   public String method(final Long dataId) {
        /* Do business */
        return URL_WITH_REDIRECT;
   }
}

プロデューサー

(ここで@ViewScoped説明されているように CDI 注釈を使用)

@ApplicationScoped
public class Producer {
   @Named @ViewScoped @Producer
   public MyBean getMyBean() {
        final MyBean bean = new MyBean();
        bean.list = new ArrayList<Data>(); // where Data has a Long id field
        /* Do business and populate list */
        return bean;
   }
}

問題とそのシナリオ

  1. GETページ
    1. 豆が産まれる
    2. ビューがレンダリングされます
    3. ブラウザーに送信された応答
  2. ボタンをクリックします
    1. データはPOSTサーバーに送信されます
    2. フェーズ1 ~ 4 は問題なく実行され@ViewScoped、期待どおりに Beanを使用します
    3. フェーズ 5:controller.methodで呼び出され、 1.1data.idで生成された Bean にアクセスします
    4. メソッドはリダイレクトを返しますString
    5. !! プロデューサーが再び呼び出されます!! - まだ APPLICATION_INVOCATION フェーズにありますが、実際のメソッド呼び出しの後です
  3. ブラウザがリダイレクトを受け取る
  4. GET次のページ ...

機能する半分「ロバ」ソリューション:

要するに、クリックすると、IDをデータテーブルの外にコピーし、送信ボタンのクリックをトリガーします。

表の列のh:commandButton内側に次のように追加されました。

onclick="$('input[id*=selectedDataId]').val('#{data.id}'); $('button[id*=callMethod]').trigger('click');"

テーブルの外:

<h:inputHidden id="{selectedDataId}"binding="#{selectedDataId}"/>
<p:commandButton type="submit"
                 id="callMethod"
                 label="Hidden button"
                 action="#{controller.method(selectedDataId.value)}"/>

最終的には機能しますが、最初と基本のアプローチがビュー スコープ Bean を再初期化する原因を突き止めることができませんでした。スタック トレース (以下を参照) を見ると、行を再構築しているように見えます。

質問:

誰かが説明を持っていますか?この問題に関して注意すべき点はありますか?

スタックトレース

ここで:getPipelinecheckSearchResultsテーブルを裏付けるリストを取得するための呼び出しであり、プロデューサーが呼び出されます

スタックトレース

私がすでに見たこと:

上記の(1番目の)ソリューションが機能する理由について理解を深めることなく、次の記事/ SOの質問を読みました。

ViewScoped Bean は、dataTable の commandButton をクリックするたびに再作成されます

Bean が @ViewScoped であるにもかかわらず、@PostConstruct コールバックが毎回起動するのはなぜですか? JSF

選択した行をdataTable内のcommandLinkに渡すにはどうすればよいですか?

http://balusc.blogspot.de/2010/06/benefits-and-pitfalls-of-viewscoped.html

https://java.net/jira/browse/JAVASERVERFACES-1492

4

2 に答える 2

0

私がこれを間違って理解している場合を除き、何らかの形でビューにスコープされた Bean を使用しています (Seam 3、CODI、または作成した独自のカスタムスコープ)。JSF ライフサイクルが同じビューで動作している限りは問題ありませんが (これは正しい仮定です)、ビュー id を変更すると、ビュー スコープ Bean の新しいインスタンスを取得することに驚かされますか?? ビュー スコープの全体的な目的は、JSF で同じビュー ステートを維持することです。JSF に別のビュー ID に移動するように指示するとすぐに、新しいビュー ステートが作成されます。あなたが実際に探しているのは、会話の範囲です。

于 2013-05-28T16:23:39.130 に答える