複雑なMVVMのヘルプ(複数のビュー)


18

次のシナリオのビューモデルの作成にヘルプが必要です。

  1. 深い階層データ
  2. 同じデータセットの複数のビュー
  3. 各ビューは、アクティブな選択に基づいて、動的に変化する単一のビューです
  4. プロパティの値に応じて、タブコントロールにさまざまな種類のタブを表示する

ここに画像の説明を入力してください

私の質問:

各ビュー(VM1、VM2など)のビューモデル表現を作成する必要がありますか?

1. Yes:
    a. Should I model the entire hierarchical relationship? (ie, SubVM1, HouseVM1, RoomVM1)
    b. How do I keep all hierarchies in sync? (e.g, adding/removing nodes)

2. No:
    a. Do I use a huge, single view model that caters for all views?

これが単一のビューの例です

図1:アクティブルームに基づいて更新された複数のビュー。通知タブコントロール

ここに画像の説明を入力してください

図2:別のアクティブルーム。複数のビューが更新されました。オブジェクトのプロパティに基づいて変更されたタブコントロール項目。

ここに画像の説明を入力してください

図3:別の選択タイプ。ビュー全体の変更

ここに画像の説明を入力してください


ところで、ムーリビューとは何ですか?打ち間違え?
JensG 14年

「ムリビュー」はタイプミスでした。同じモデル/ビューモデルに対して異なるビューを意味しました。私の質問は、各ビューのモデル階層全体を再構築/ラップする必要があるので、各ビューモデルには個々のビューに必要なものだけが含まれますか?または、すべてのビューのプロパティを含む単一のビューモデル階層を作成する必要がありますか?私はこの質問を投稿して以来、この2つの長所/短所を見つけるのに十分な(不幸な)苦労でした。忙しくないものであれば、私の経験を完全に診断して、将来このスレッドを更新します。
jayars 14年

設計ルールは、最初に一般的なことを示してから詳細に深く入り込むことです。明るいビューが表示され、ユーザーがさらに深くなると新しいビューが表示されます。そのため、ビューモデルを分けて小さなビューを使用します。この記事をチェックデザインのユーザーインターフェース
Csharls

@jsjslim「すべての階層を同期させる」を読んだとき、私は身震いしました。私はあなたがマルチビューで行ったと思う、そしてあなたはそれを後悔していると思う(しかし私は前に間違っていた)。同じ質問を持っているかもしれない他の読者のために、少なくとも私たちに簡単な(少し)答えをいただけますか?
ガイシャルナ14

2
@ guy-schalnatマルチビューは必須でした。私の問題は、ビューモデルを構築する方法を見つけようとしていました。プロジェクトはまだ進行中であり、完全な分析を書き上げる時間を見つけることができません。しかし、要約すると、モデル構造を無視し、ビューに焦点を合わせる必要がありました。私が遭遇した複雑さは自発的なものでした。WPFのデータバインディングをひどく使用したかったので、気が狂いました。最後に私がやったことは、古くからある「コピー/貼り付け/リファクタリング」でした。登場した最終設計は軽量で(繰り返しはほとんどありませんでした)、さらに重要なことは機能していました。将来的に完全な分析を作成します。
jayars 14

回答:


13

質問に答えるには、はい、各ビューには独自のビューモデルが必要です。ただし、階層全体をモデル化する必要はありません。ビューに必要なもののみ。

MVVMに関するほとんどのオンラインリソースで発生した問題:

ほとんどの例では、ビューはモデルのほぼ1対1のマッピングです。しかし、同じモデルのさまざまなファセットにさまざまなビューが存在する私のシナリオでは、2つの選択肢の間で立ち往生しています。

他のすべてのビューモデルで使用される1つのモノリシックビューモデル

ここに画像の説明を入力してください

または、各ビューに1つのビューモデル

ここに画像の説明を入力してください

しかし、両方とも理想的ではありません。

モデル指向のビューモデル(MVM)は、コードの重複は少ないですが、維持するのは悪夢です

ビュー指向ビューモデル(VVM)は、各ビューに対して高度に専門化されたクラスを生成しますが、重複を含みます。

最終的に、Viewごとに1つのVMを保持する方が保守とコーディングが簡単であると判断したため、VVMアプローチを採用しました。

コードが機能したら、すべての一般的なプロパティと操作を現在の最終形式にリファクタリングし始めました。

ここに画像の説明を入力してください

この最終形式では、共通ビューモデルクラスが各VVMに構成されます。

もちろん、私はまだ一般的/専門と見なされるものを決定する必要があります。また、ビューが追加/マージ/削除されると、このバランスが変化します。

しかし、これの良いところは、メンバーを共通からVVMへ、またはその逆に簡単にプッシュ/ダウンできるようになったことです。

そして、オブジェクトの同期を保つことに関する簡単なメモ:

共通ビューモデルを持つことで、このほとんどが処理されます。各VVMは、単純に同じ共通ビューモデルへの参照を持つことができます。

また、単純なコールバックメソッドから始め、複数のリスナーの必要性が生じた場合はイベント/オブザーバーに進化する傾向があります。

そして、本当に複雑なイベント(つまり、予期しないカスケード更新)の場合、メディエーターの使用に切り替えます。

子が親への後方参照を持っているコードを敬遠しません。コードを機能させるためのあらゆるもの。

そして、リファクタリングの機会が生じた場合、私はそれを取るでしょう。

私が学んだ教訓:

  1. glyい/作業コード>美しい/非作業コード
  2. 巨大なクラスを分割するよりも、複数の小さなクラスをマージする方が簡単です

これを2回支持できたらと思います。これは、私が見たオプションの最も明確な説明の1つです。
巧妙な人間

3

モックアップを見ると、ViewModelの階層と多数の小さなビューを作成することをお勧めします。そして、おそらく元の階層のかなりの部分をモデル化する必要があります。

ViewModel間の同期を維持するには、いずれかのイベントを使用するか、ViewModel間で相互にプロパティを設定します。ビューとViewModel間の同期は、標準の通知プロパティである必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.