web-dev-qa-db-ja.com

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

次のシナリオでのビューモデルの作成についてサポートが必要です。

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

enter image description here

私の質問:

各ビュー(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:アクティブな部屋に基づいて更新された複数のビュー。タブコントロールに注意してください。

enter image description here

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

enter image description here

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

enter image description here

18
jayars

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

MVVMに関するほとんどのオンラインリソースで私が抱えていた問題:

ほとんどの例では、ビューはモデルのほぼ1対1のマッピングです。しかし、同じモデルの異なるファセットに対して異なるビューがある私のシナリオでは、私は2つの選択肢の間で行き詰まっています。

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

enter image description here

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

enter image description here

しかし、どちらも理想的ではありません。

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

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

最後に、私は1つのVMビューごとに維持することとコーディングが容易であることを決定したので、VVMアプローチを採用しました。

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

enter image description here

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

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

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

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

Common View Modelがあれば、このほとんどを処理できます。各VVMは、同じ共通ビューモデルへの参照を持つことができます。

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

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

私は、子が親への後方参照を持っているコードを避けません。コードを機能させるためのもの。

そして、リファクタリングの機会が生じたら、私はそれを採用します。

私が学んだ教訓:

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

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

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

3
Euphoric