MVVMで状態を管理するための良い正式なパターンはありますか?


21

私はウェブの世界でReduxとReactについて学び始めましたが、それについて学べば学ぶほど、WPFのMVVMスタイルのアーキテクチャ(特にビューをバインドするためにCaliburnを使用して) ViewModelsへ)。

Reduxには、状態の管理方法を指示するいくつかの簡単な原則があり、UIの更新、イベント処理、状態の変更をより予測可能にします。原則は次のとおりです。

  • 単一の真実のソース(すべての可変状態は単一の共有オブジェクトに格納されます)。
  • 状態は読み取り専用です。コード全体でコンポーネントによって変更することはできません。これは通常、WPFで発生することです。
  • 状態は、純粋な関数によってのみ変更できます。

WPFのMVVMアーキテクチャを使用すると、インタラクティブビューを非常に迅速に構築できますが、さまざまなビューモデルやイベントがすべて状態を変更する場合のデバッグの問題は悪夢です。たとえば、ビューを変更してデフォルトのタブを設定しようとしたイベントが発生しましたが、Webサービスからのデータの非同期読み込みが完了していないため、タブはまだ存在しないため、何も起こりません

相互に更新する相互に関連するviewModelsコンポーネント間の複雑な相互作用を理解するために、私は何時間も図を描きました。

Reduxは、この状態の予測不可能性の一部を解決することを目指していることを理解しています。状態の管理を改善するために、WPFにうまく適合する類似の何か、またはアーキテクチャパターンがありますか?Reduxの原則が.NETでどの程度うまく機能するかは、まだ試していませんのでわかりません。おそらく誰かがいくつかのアドバイスを与えることができるいくつかの経験を持っていますか?


ブラウザにも同様の問題があります。簡単なJavascriptは非常に早く実行され、DOMはまだ構築されていないため、UI要素を見つけることができません。幸いなことに多くのイベントがあり、他のものがさらに進むまで、いくつかのスクリプトの遅延実行をトリガーするために使用できます。(DOMContentLoadedなど)
Erik Eidt

1
reduxの状態は実際に更新され、変更されることはありません。
アンディ

1
私はパーティーに遅れていることは知っていますが、Reduxアーキテクチャを.NETにもたらすReact.NETと呼ばれるプロジェクトがあります。
SiberianGuy

Angularプロジェクトでのngrx / storeのアプローチが好きな人のために、ngrx / storeに触発された.Netプロジェクトの状態管理であるNetRx.Storeがあります。Nugetでも見つけることができます。また、WPFプロジェクトのMVVMパターン
Vitalii Ilchenko

回答:


8

私はあなたが何を意味するか知っていると思います。基本的に、「コントローラー」または「マスター」ビューモデルのいずれかを追加して問題を解決します(psudocodeを言い訳)

すなわち

public class MasterVM
{
    public ChildVM View1 {get;set;}
    public ChildVM View2 {get;set;}

    private Data data;
    public MasterVM()
    {
        View1.OnEvent += updateData;
    }

    private Action<int> updateData(int value)
    {
         View2.Value = value;
    }
}

Mediatorパターンを使用してこれを行う場合、クラスをコントローラーと見なします。すなわち。

public class Controller
{
    public Controller(MediatorService m)
    {
        m.Subscribe("valueupdated", updateData);
    }

    private Action<int> updateData(int value)
    {
         m.Publish("showvalue", value);
    }
}

public class View2
{
    public View2(MediatorService m)
    {
        m.Subscribe("showvalue", (int v)=> {Value = v;});
    }
}

この種のことにより、これらの高レベル永続クラスに「フローロジック」またはイベントオーケストレーションを配置し、VMコードを軽量に保つことができます。「ユーザーがBUYをクリックしたときに注文が処理される」という種類の「OrderFlowController」または「OrderProcessVM」で確認すること、または名前を付けたいことを変更する場合。BasketVM、PaymentVM、3dSecureVMなどの組み合わせではなく

したがって、「タブがまだ準備できていません」という特定の例では、

public class Controller
{
    bool dataLoadCompleted;
    public Controller(MediatorService m)
    {
        m.Subscribe("setTabRequest", setTab); //message from view model with set tab button
        m.Subscribe("dataLoadComplete", dataLoadComplete); //message from data loading view model or some other controller?
    }

    private Action<int> setTab(int value)
    {
         if(!dataLoadCompleted)
         {
             m.Publish("error", "Please wait for data to load"); //message for error alert view model
         }
         else
         {
             m.Publish("setDefaultTab", value); //message for tab viewmodel
         }
    }

    private Action dataLoadComplete()
    {
         //persist state;
         dataLoadCompleted = true;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.