39

MVVMの実装では、すべてがViewModel1つだけに結合されていModelますか?

プロジェクトにMVVMパターンを実装しようとしていますがView、複数の情報が必要になる場合がありますModels

たとえば、のUserProfileView場合、、、などからのUserProfileViewModel情報が必要になる場合があります。UserAccountModelUserProfileSettingsModelUserPostsDataModel

ただし、MVVMについて読んだほとんどの記事では、ViewModelは依存性注入による1つのモデルのみで構成されています。したがって、コンストラクターは1つのモデルのみを取り込みます。

ViewModel複数から情報を取得する必要がある場合、どのように機能しますModelsか?それとも、MVVMでそのような状況が発生する可能性はありますか?

PS:私はPrismまたはUnityFrameworkを使用していません。PrismやUnityを使用しないプロジェクトに同様のパターンを実装しようとしています。そのため、これらのいくつかがどのように機能するかを正確に理解する必要があります。

4

7 に答える 7

47

MVVMパターンの私の理解では、唯一の実際的な要件は、ViewがViewModelのプロパティから(おそらくバインディングメカニズムを介して)すべてのデータを取得することです。ViewModelは、そのビュー用に特別に作成したクラスであり、必要に応じて自分自身にデータを入力する責任を負います。ビューのActiveRecordのように考えることができます。

そのため、ViewModel内で何をして、そのプロパティが表示する必要のあるデータを取得するかは重要ではありません。いくつかのサービスにクエリを実行するか、1つ以上のビジネスエンティティモデルを読み取るか、その場で生成するか、または上記のすべてによって取得できます。機能的なビューを作成するためにこれらすべての組み合わせが必要になるのは、まったく正常なことです。

他のプレゼンテーションパターンと同様に、重要なのは、画面にデータを表示するプロセスと、そのデータを取得するプロセスを分離することです。そうすれば、プロセスの各部分を個別にテストできます。

編集:これは、依存関係のフローの小さいがうまくいけば完全な例です。

// Model/service layer

public class MyModelA
{
  public string GetSomeData()
  {
    return "Some Data";
  }
}

public class MyModelB
{
  public string GetOtherData()
  {
    return "Other Data";
  }
}

// Presentation layer

public class MyViewModel
{
  readonly MyModelA modelA;
  readonly MyModelB modelB;

  public MyViewModel(MyModelA modelA, MyModelB modelB)
  {
    this.modelA = modelA;
    this.modelB = modelB;
  }

  public string TextBox1Value { get; set; } 

  public string TextBox2Value { get; set; }

  public void Load()
  {
    // These need not necessarily be populated this way. 
    // You could load an entity and have your properties read data directly from it.
    this.TextBox1Value = modelA.GetSomeData();
    this.TextBox2Value = modelB.GetOtherData();
    // raise INotifyPropertyChanged events here
  }
}

public class MyView
{
  readonly MyViewModel vm;

  public MyView(MyViewModel vm)
  {
    this.vm = vm;
    // bind to vm here
  }
}

// Application layer

public class Program
{
  public void Run()
  {
    var mA = new MyModelA();
    var mB = new MyModelB();
    var vm = new MyViewModel(mA, mB);
    var view = new MyView(vm);
    vm.Load();
    // show view here
  }
}
于 2012-10-26T11:18:43.270 に答える
14

ビューモデルで複数のモデルを使用できます。ビューモデルの目的は、ビジネス/データレイヤー(つまりモデル)を抽象化することです。

ただし、複数のモデルを使用する場合は、通常、ビューが大きすぎることを示しています。これをユーザーコントロール(独自のビューモデルを持つ)に分割することをお勧めします。

于 2012-10-26T11:07:51.790 に答える
4

ビューモデルには「ビューロジック」が含まれているため、ビューに表示したいものはすべてビューモデルを通じて公開されます。異なる「モデル」からのデータを表示したい場合は、ビューモデルがこれを集約し、ビューをバインドできます。

mvvmの主な目的はbtwユニットテストでした。これは、UIなしでビューロジックを簡単にテストできることを意味します。

編集:なぜあなたは思いますか:

ViewModelのコンストラクターには、ビューのパラメーターが1つだけあります。

EDIT2:

mvvmを操作するための2つの主要なアプローチがあります。最初は「ViewFirst」、2番目は「ViewmodelFirst」です。もちろん、両方を組み合わせて、ニーズに最適なアプローチを選択できます。

于 2012-10-26T11:31:55.447 に答える
2

ViewModelは、多くの場合、複数のモデルを使用する場合があります。それ自体があなたの見解の「モデル」です。

ユーザーが住所などの個人情報を入力するプロファイル画面について考えてみます。アドレスが「アドレス」テーブルに格納され、残りが「プロファイル」テーブルに格納されている場合、ViewModelはプロファイルモデルとアドレスモデルの両方を使用して、統合されたViewModelを作成します。

jgauffinが彼の回答で述べたように、多くの場合、ユーザーコントロールを使用して、1対1の関係を実現できますが、これを100%試行することで、不必要な複雑さを導入することもできます。

于 2012-10-26T11:12:16.317 に答える
2

view、viewmodel、および他のすべてのモデルクラスの違いを理解してください。ViewModelは、ビューをバインドできるデータで満たされたモデルオブジェクトです。これは、ビューにデータを提供するためだけに存在します。これにより、ViewModelオブジェクトがユニットテスト可能になり、ビジネスロジック全体がビューから分離されます。したがって、ビュー自体を使用せずにビジネスロジックを完全に開発でき、ビューを、別のビューを構築または使用してViewModelオブジェクトのプロパティにバインドするだけで置き換えることができます。たとえば、ビューが空のテキストフィールドでいっぱいの場合、テキストフィールドのコンテンツをビューモデルのさまざまなプロパティにバインドできます。

通常、実際には1つのビューモデルのみが存在する必要があります。ただし、複雑すぎる場合は、「ViewModel.SubClass.Propertyへのバインド(サブプロパティ)」で説明されているように、バインドされたオブジェクトのサブプロパティを使用できます。

ViewModelは、さまざまなソース、ビジネスオブジェクト、データベースなど、さまざまなソースからビューに返すデータを取得できます。

于 2012-10-26T11:13:15.827 に答える
1

通常、モデルごとに1つのViewModelがあります。これらのViewModelには、モデルのデータを処理するためのロジックが含まれています。一方、すべてのビューには独自のビューモデルもあります。つまり、これは次のことを意味します。

class ModelA 
{
    bool TestValue{get;set;}
}
class ViewModelA<ModelA>
{
    ValueViewModel<bool> TestValue{get; private set;}

    public ViewModelA(ModelA model) 
    {
        base.Model = model;
        this.Initialize();
    }
}

class ModelB 
{
    string Username;
}
class ViewModelB<ModelB>
{
    ValueViewModel<string> Username{get; private set;}

    public ViewModelB(ModelB model) 
    {
        base.Model = model;
        this.Initialize();
    }
}

これらは、モデルをカプセル化するViewModelです。ビューには独自のViewModelがあります。

public ViewModelForExactlyOneView
{
    public ViewModelA{get;set;}
    public ViewModelB{get;set;}
}

あなたの質問に答えるために、ViewModel1はViewModelAとViewModelBを参照します。したがって、ビューはからデータを取得できますViewModel1.ViewModelA.TestValue

于 2012-10-26T11:05:21.823 に答える
-4

ビューでユーザーモデルを使用するだけです

public partial class User : Login
{
    public string Password { get; set; }

    public List<Customer> customer { get; set; }
}

これでは、別のモデルのログインが継承され、顧客モデルもこのモデルで使用されます。

于 2015-06-17T09:35:06.107 に答える