5

MVVMベースのシングルページアプリケーションを実装しようとしていますが、現在、フレームワークKnockout.jsを使用してMVVMのviewmodel/view部分を処理しています。ただし、Knockoutを実装するために見たすべての例では、ビューモデル全体をデータベースに保存する必要があるため、混乱しています。これらの例では、ビューモデルがデータレイヤーモデルと同期し、モデルが検証/サーバー同期を行う「モデル」ステップが欠落していませんか。

1つのページに複数の異なるテンプレート/ビューをそれぞれ異なるビューモデルで表示したいと思います。私が見つけたもう1つのことは、knockout.jsに欠けていることです。それは、異なるビュー間で単一のモデル(viewmodelではない)を同期することです。すべてのビューが共有する1つの巨大なビューモデルを持つことは意味がないと思うので、各ビューには独自のビューモデルがあると思っていましたが、各ビューモデルは、に必要ないくつかのアプリケーション全体のモデルのフィールドと同期します各ビュー。

私が取り組んでいるページは巨大なモデル(30以上のフィールド、親子関係の複数のレイヤー)をフェッチし、すべてのビューモデルをこのモデルと同期させるのは理にかなっていると思います。Knockback.js(knockout.jsとbackbone.jsを組み合わせたもの)を調査しましたが、ページがAPIからデータを取得しているため、フェッチ、設定、保存などの関数の大部分を書き直すことになりました(モデル全体をサーバーと前後に同期するだけではないので、私はそれに反対することにしました。

私のアプリケーションの視覚的な例:

(モデルレイヤー)M | M

(ビューモデル/ビューレイヤー)VM-V | VM-V | VM-V | VM-V


もう一つの例

モデルの例は、User = {firstName: "first"、lastName: "last"、...}

1つのビューモデルには名のみが必要であり、別のビューモデルには姓のみが必要です
ViewModelA = {firstName:app.User.firstName()}
ViewModelB = {firstName:app.User.lastName()}

モデルとビューモデルの変更のためにpub/subシステムを定義するためにこれを行う唯一の方法はありますか?これは、優れた/保守可能なアーキテクチャでもありますか?ここで基本的な概念が欠けていますか?すべてのアドバイスを歓迎します。

4

4 に答える 4

5

これを正しく読んだ場合、ここにはノックアウトを使用してMVVM/SPAを構築する方法に焦点を当てた多くの質問があります。ご指摘のとおり、取り組むべきことがいくつかあります。1つは、viewmodel/viewペア間で通信する方法です。

マスター ビューモデルこれを行う1つの方法は、@Tyrsiusからの回答としてマスタービューモデルを使用することです。シェルには、より多くの利用可能なデータをバインドするビューモデルを含めることができます。マスタービューモデルは、子ビューモデルを調整することもできます。このルートを使用する場合は、外側のシェルをマスタービューモデルにバインドし、内側のシェルをDOM内の特定のHTML要素にバインドするように注意する必要があります。マスタービューモデルは、必要に応じてそれらの間の通信を容易にすることができます。

分離されたビュー/ViewModelペア 別のオプションは、ビューモデル/ビューペアを使用し、マスタービューモデルを使用しないことです。各ビューはDOMの領域に読み込まれ、独自にバインドされます。それらは別々のユニットとして機能し、互いに分離されています。pub / subを使用して、の間で通信することもできますが、必要なのがオブザーバブルを介してデータを同期する方法だけである場合、Knockoutには多くのオプションがあります。私が気に入っているのは、各ビューモデルのサーフェスモデルオブジェクトを用意することです。したがって、ビューには、ビューに固有の(モデルからの)データを表示するビューモデルがあります。非常に多くのビューモデルが、同じモデルをさまざまな方法で表示する場合があります。したがって、ビューが(モデル内の)viewmodelプロパティを更新すると、同じモデルを使用する他のロードされたビューモデルに波及します。

DataContext もう少し進んで、モデル内のデータを管理するdatacontextモジュールを作成できます。datacontextにモデル(例:顧客のリスト)を要求すると、datacontextは、モデルがすでにcahcedされているかどうかを確認し、そうでない場合は、ajax呼び出しから取得します。どちらの方法でも、ビューモデルとモデルから抽象化されます。datacontextはデータを取得し、モデルをビューモデルに返します。このようにして、非常に分離されていますが、データコンテキストを介してデータ(モデル)を共有できます。

私は何度も続けることができます...しかし、これがあなたの質問に答えているかどうか教えてください。そうでない場合は、他の詳細に喜んでお答えします。

**免責事項:私はSPAでPluralsightコースを構築しています(ノックアウトとこの戦略を使用):-)

于 2012-06-28T20:10:12.360 に答える
2

これは現在人気のある分野なので、もっと良い答えが得られると思いますが、ここで説明します。

モデル

はい、モデルであるデータのサーバー側表現が絶対に必要です。これが何であるかは、サーバーとデータベースによって異なります。MVC3の場合、これはエンティティモデルです。DjangoまたはRubyの場合、dbセットアップの一部としてdbモデルを定義します。この部分はあなたの特定の技術次第です。しかし、agian、はい、モデルが必要であり、サーバーは絶対にデータ検証を実行する必要があります。

アプリケーション(ViewModel)

ビューにはそれぞれ独自のビューモデルを含めることをお勧めします。その場合、ページには、それらすべてを追跡するビューモデル(必要に応じてアプリビューモデル)を含めることもできます。このルートを使用する場合、アプリのビューモデルは、ビューを切り替えたり、他のアプリケーションレベルのロジック(ハッシュバッシュナビゲーション、別の人気のあるシングルページツールなど)を実装したりする必要があります。この階層は非常に重要ですが、必ずしも単純ではありません。それはあなたのアプリケーションの特定の要件に帰着します。1つのフラットビューモデルに限定されません。これが唯一の可能な方法ではありません。

アドホックの例:

​var ThingViewModel = function(name, data){
    this.name = ko.observable(name);
    //Additional viewmodel stuffs
};

var AppViewModel = function(initialData){
    //Process initial data    
    this.thing = new ThingViewModel(someName, someData); 

};

私は現在、純粋に研究のために(実際のアプリではなく)同様のプロジェクトに取り組んでいます。これは、実際の例を見てみたい場合は、ここGitHubでホストされています。dev現時点では、ブランチはブランチよりかなり進んでいることに注意してくださいmaster。いくつかの悪いパターンが含まれていると確信しています(私も学んでいます)が、とにかくそれからいくつかのことを学ぶことができるかもしれません。

于 2012-06-28T18:50:36.967 に答える
1

同様に複雑なソリューションがあり、WPFアプリケーションをWebバージョンに作り直しています。WPFバージョンは、プレゼンターモデルを介してビューにバインドされた複雑なドメインオブジェクトを処理しました。

Webバージョンでは、Automapperを使用してドメインオブジェクト間で前後に変換される、簡略化されたややフラット化されたサーバー側ビューモデルを実装しました。次に、これらのサーバー側ビューモデルはJSONとしてクライアントとの間で送受信され、マッピングプラグインを使用して対応するノックアウトビューモデル(それぞれがサブマッピングオプションを使用して子を作成する責任を負うインスタンス化可能な関数)にマッピングされます。

UIを保存/検証する必要がある場合は、Knockoutビューモデルのすべてまたは一部をプレーンなJavascriptオブジェクトにマップし、JSONとして投稿します。MVCフレームワークは、サーバー側のビューモデルにバインドし、これらはAutomappedに戻ります。ドメインオブジェクトは、ドメインレイヤーによって検証され、場合によっては更新されます。その後、改訂された完全または部分的なグラフが返され、再マップされます。

現在、ノックアウトアクションが実行されるメインページは1つだけですが、あなたのように、同じモデル(私のドメインオブジェクト)を処理する必要がある複数のコンテキストが、私が何に応じて異なるビューモデルとしてプルされるかを予測します。彼らと一緒にやっています。

これを見越してサーバーサイドビューモデルディレクトリなどを構造化し、ノックアウトビューモデルの構造も構築しました。これまでのところ、このアプローチはうまく機能しています。お役に立てれば。

于 2012-06-29T04:46:17.520 に答える
0

プロジェクト中に、分離されたView / ViewModelペアを提供し、ビュー内のサブビューをインスタンス化できるフレームワーク(KnockoutJSを使用)を開発しました。ビューとサブビューのインスタンス化の全体的な処理は、フレームワークによって提供されます。これは、WPFのXAMLを使用したMVVMのように機能します。

http://visto.codeplex.comをご覧ください

于 2013-09-13T14:40:48.063 に答える