5

要するに、私が求めているのは、MVC4パーシャルビューのノックアウトバインディング/ javascriptオブジェクトにスコープ/コンテキストを提供する方法です。これにより、同じパーシャルを互いに干渉することなく再利用できますが、それでも可能です。クライアント側で親子ビューモデルを参照します。

ノックアウト初心者(そして実際にはもっと広くWeb開発者)としては非常に可能性があります。ここでは一般的なjavascriptの概念パターンが欠落していますが、私が遭遇しているシナリオは次のようなものです。サーバー上にビューモデルがあります。たとえば、次のように言います。

public class MainModel 
{
    // Other fields 

    SubviewModel Subview { get; set}
}

public class SubviewModel 
{
    // Relevant subview fields
}

次に、強く型付けされた(メイン)部分ビューで、必要なものをレンダリングし、@ Html.Actionを介してサブビューモデルを(サーバー上で)強く型付けされた部分ビューに渡します。どちらの場合も、次のようにしてノックアウトを設定しています。

var mvcModel = ko.mapping.fromJS(@Html.Raw(JsonConvert.SerializeObject(this.Model)));

ko.applyBindings(mvcModel , document.getElementById("@("divSubview"+Model.Guid)"));

この場合、divSubviewがパーシャルのメインラッパーdivになり、通常、すべてが正常にバインドされます(ほぼ)。

Model.Guid連結は、最初の問題に対処するためにあります。これは、これらのパーシャルが通常、さまざまなビューモデルのページに複数レンダリングされることです。(アイテムのリスト、ToDoリストなどと考えてください。各アイテムには、変更される可能性のあるサブコンテンツがあります。おそらく、さらに説明する前に、アイデアがわかります...)したがって、複数のパーシャルが同じページにレンダリングされる場合、divの名前が一意でない場合、document.getElementByIdを介してapplyBindingsを呼び出すと、2番目のviewModelをその名前で最初にレンダリングされたdivに適用することになります。

2番目の問題は、メインパーシャル(特定のページに複数あります)をレンダリングしてからサブビューをレンダリングするときに、サブビューのメインビューモデルまたは同様のものを参照したい場合が多いという点で関連しています。私が使用している回避策は、名前付きグローバルパラメータを設定し、スクリプトが順番に実行されることがわかっているので、それを使用して前後に参照することですが、これはかなりハックです。

それで、私が見逃している正しい解決策は何ですか?

Knockoutのテンプレートと1つの大きなビューモデルを使用できることはわかっていますが、最終的にはそれが適切なソリューションになる可能性がありますが、今のところ、MVCパーシャル(サーバーに緊密に結合されている)では、提供したくないことがたくさんあります。上。(そして次に、バインディングなどでパフォーマンスに少し影響を与えている場合でも、今のところ、少なくともクライアントでは、パーシャルをできるだけ緩く結合したままにしようとしています。)

私が本当に求めているのは、ある形式のスコープをパーシャルに渡す方法です。これにより、サブビューパーシャルは、グローバル名前空間を汚染したり、一意の名前空間を使用したりすることなく、メインのパーシャルビューモデル(および同様に)を参照できます。名前。子/親パーシャルのオブジェクトへの参照を持つクライアント側のJS変数を示す方法はありますか?(または、私は完全に要点を見逃していて、はるかに良い方法がありますか?)

4

1 に答える 1

1

長期的には、弾丸を噛み、マッピングプラグイン、初期化するページにレンダリングされたトップレベルビューモデルのJSON表現、およびサブビューモデルのテンプレートの古典的な組み合わせを使用するのが本当に最善かもしれません。しかし、既存のMVC部分ロジックに関するあなたの苦痛を理解しているので......

現在、各サブパーシャルのビューの一部として個別のスクリプトブロックをレンダリングして、ノックアウトビューモデルを作成し、そのバインディングを適用していますか?

単一のバインディングコンテキストを回避して、トップレベルのビューモデルを所有し、サブパーシャルがレンダリングされるときに子ビューモデルが段階的に追加され、次にページの下部にある、ある種のモジュールをページで定義できませんでした。 、DOMの準備ができたら、バインディングを適用しますか?

したがって、各サブパーシャルのスクリプトブロックは、モジュール上の関数を呼び出して、そのGuidキーを含むサブモデルの生のJSONを渡します。次に、モジュールはサブビューモデルの新しいインスタンスを作成し、その中の参照として親ビューモデルを設定し、それを親ビューモデルのサブビューモデルの監視可能な配列にプッシュします。次に、それぞれの方法で参照があります。

この構造に何らかのページレベルマネージャーを使用することを回避できるかどうかはわかりません(グローバル名前空間を汚染しないという意味の場合)。いずれにせよ、これらの部分ビューモデルをすべて、グローバル名前空間にフローティングするのではなく、単一のオブジェクトで所有するのは良いことではありませんか?(もしそうなら)

私があなたの文脈を正しく理解していることを願っています。

更新:あなたのパーシャルは、ある意味でまだ緩く結合されています。マークアップのバインディング式は明らかにサブビューモデルのインスタンスに関連している必要がありますが、それはToDoリストアイテムなどのforeachを介してチェーンされたデータコンテキストであるか、「with」式を使用して明示的に設定されます。たとえば、someOtherModule.randomStandaloneSubViewModelを使用します

于 2012-11-16T23:00:52.277 に答える