1

いくつかの一般的な要素と、さまざまなユーザーアクションに基づいて動的にロードおよび含まれる4つの部分を含むJSFページがあります。さまざまなインクルードの機能をカプセル化したBeanがあり、構造は次のようになります。

mainview.xhtml 
     --backed by--> mainViewBean (request scope) 
       --with managed property--> mainViewView (view scope)

include1.xhtml
     --backed by--> include1Bean (request scope)
       --with managed property--> mainViewBean

include2.xhtml
     --backed by--> include2Bean (request scope)
       --with managed property--> mainViewBean

include3.xhtml
     --backed by (and with component bindings to)--> include3Bean (request scope)
       --with managed property--> mainViewBean

include4.xhtml
     --backed by--> mainViewBean

メインビューページでは、BalusCが次の質問で説明しているように、条件付きでレンダリングされた一連のh:panelGroupsを介して各インクルードが含まれています。

https://stackoverflow.com/a/9897016/945403

https://stackoverflow.com/a/7113961/945403

ビュースコープBeanには、ユーザーのアクティビティの現在の状態、ユーザーが現在表示しているアイテムなどに関するさまざまなビュー情報が含まれています。

含まれている各ビューは、ajax投稿と非ajax投稿の両方を介してさまざまなタスクを実行します。私の問題は、特定のパネルでの特定のアクションによってビュースコープが破壊されているように見え、韻や理由がないように見えることです。以下に概説する複雑なワークフローについては、事前にお詫び申し上げますが、できる限り明確にするよう努めます。

include3.xhtmlでajaxアクションを実行すると、コンポーネントはインクルード内でのみレンダリングされ、1日中実行でき、ビュースコープは残ります。ajax以外の投稿を実行すると、更新によってinclude4.xhtmlが更新されます(以前にレンダリングされなかったものが追加される可能性があります)。その後、他のインクルードのいずれかでアクションを実行できます。

include1.xhtmlでajaxアクションを実行すると、それ自体のバッキングBeanのメソッドのみが呼び出され、独自のコンポーネントのみが更新されますが、ビュースコープは残ります。include3Beanのメソッドを呼び出してinclude2.xhtmlとinclude3.xhtmlを含むdivを更新するajaxアクションを実行すると、ビュースコープは残り、include1.xhtmlでアクションを実行し続ける限り、ビュースコープは残ります。他のインクルードの1つで別のアクションを実行しようとすると、ビュースコープが破棄されます。

この時点で、問題は、アクションが呼び出されているのとは異なるインクルードを更新していることにあるに違いないと思いました。しかし、これから説明するように、これが問題(または少なくとも唯一の問題)ではないようです。

include2.xhtmlにはajaxアクションがあり、起動すると、mainViewBackingのメソッドを呼び出し、include2.xhtmlとinclude3.xhtmlを含むdivを更新します。このアクションを引き続き実行するか、include2.xhtmlで他のアクション(非ajaxアクションを含む)を実行すると、すべてが期待どおりに機能し、ビュースコープは残ります。ただし、その後include3.xhtmlでアクションを実行すると、ビュースコープが破棄されます。これがおかしくなるのは、include1.xhtmlでアクションを実行でき、必要な限りビュースコープにアクセスし続けることですが、戻ってinclude2.xhtmlまたはinclude3でアクションを実行しようとすると。 xhtml、ビュースコープが再び失われます。

私はこの時点で少し立ち往生していて、何が悪いのかを理解する方法さえわかりません。インクルードを更新(および削除または追加)すると、ビュースコープが失われると思いますが、以前にリンクされた質問から、UIの実際のsrc値として、これは問題ではないようです。 :includesは動的に生成されていません。そして、mainview.xhtmlの部分的な状態保存をオフにしています。

これらの動的に表示されるui:includesについて、ビュースコープを壊す何かがありますか?

4

1 に答える 1

3

2014-02-28を編集:

最新のオムニフェイスのショーケースを見ていると、BalusCがこの同じ問題を解決するスクリプトを実装していることに気付きました。おそらく、以下のコードよりもはるかに優れた方法で実行できます。

http://showcase.omnifaces.org/scripts/FixViewState

元の回答:

BalusCがここで説明しているように、これはJSFのバグであることが判明しました:http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#AjaxRenderingOfContentWhichContainsAnotherForm

残念ながら、彼の解決策は、何らかの理由で私にとって一貫して機能しませんでした。その結果、私は自分自身の(もう少し厄介な)回避策を作成しました。これは、他の人が必要とする場合にここで提供します。

mainview.xhtmlページに次のJavaScriptを追加しました。

var lastForm = null;

        function getViewStateFromLastForm(callingElement){

            var currentForm = $(callingElement).closest("form");
            var formId = currentForm.attr("id");

            if(lastForm != null ){
                var viewState = $("#" + lastForm).children("[name='javax.faces.ViewState']").val();
                currentForm.children("[name='javax.faces.ViewState']").remove();

                $('<input/>').attr({
                    type: 'hidden',
                    id: 'javax.faces.ViewState',
                    name: 'javax.faces.ViewState',
                    autocomplete: 'off',
                    value: viewState
                }).appendTo(currentForm);
            }
            lastForm = formId;

        }

次に、サーバーに送信されるさまざまなインクルードページのすべてのボタンでgetViewStateFromLastForm(this);、onclick属性が呼び出されます。

于 2012-09-20T14:37:51.877 に答える