MVVM'de durumu yönetmek için iyi bir resmi model var mı?


21

Web dünyasında Redux ve React'i öğrenmeye başladım ve ne kadar çok öğrenirsem WPF'nin MVVM tarzı mimarisi ile masaüstü dünyasında ne kadar acı verici devlet yönetiminin olduğunu daha çok anlıyorum (Views'ı bağlamak için Caliburn'u kullanarak ViewModels'e).

Redux, devletin nasıl yönetilmesi gerektiğini belirleyen, UI güncellemelerini, olay işleme ve durum değişikliklerini çok daha öngörülebilir kılan birkaç basit ilkeye sahiptir. İlkeler:

  • Tek bir hakikat kaynağı (değişebilir tüm durum tek bir paylaşılan nesnede saklanır).
  • Durum salt okunurdur. Kod aracılığıyla bileşenler tarafından değiştirilemez, bu genellikle WPF'de olan şeydir.
  • Durum yalnızca saf işlevlerle değiştirilebilir.

WPF'nin MVVM mimarisi, çok hızlı bir şekilde etkileşimli görünümler oluşturmanıza izin verir, ancak çeşitli görünüm modelleri ve olayların tümü durum değiştirdiğinde hata ayıklama sorunları bir kabus olur. Örneğin: bir görünümü değiştiren ve varsayılan bir sekme ayarlamaya çalışan bir olay tetiklendi, ancak veriler bir web hizmetinden eşzamansız olarak yüklenmeyi tamamlamadı, bu nedenle sekme mevcut değil (henüz), bu yüzden hiçbir şey olmuyor

Birbirini güncelleyen birbiriyle ilişkili viewModels bileşenleri arasındaki karmaşık etkileşimleri denemek ve anlamak için diyagramlar çizerek saatler geçirdim.

Redux'un bu durumun öngörülemezliğinin bir kısmını çözmeyi amaçladığını anlıyorum. Devletin daha iyi yönetilmesine yardımcı olmak için benzer bir şey veya WPF ile iyi uyum sağlayacak bir mimari desen var mı? Henüz denemediğim için Redux ilkelerinin .NET'te ne kadar iyi çalışacağından emin değilim. Belki birisinin tavsiyede bulunabilecek bir tecrübesi vardır?


Tarayıcıda benzer bir sorun yaşıyoruz. Basit Javascript bu kadar erken çalışır ve DOM henüz oluşturulmamıştır, bu yüzden kullanıcı herhangi bir UI öğesi bulamaz. Neyse ki bir takım Olaylar var, başka şeyler ilerleyene kadar bazı komut dosyalarının gecikmeli yürütülmesini tetiklemek için kullanabiliriz. (DOMContentLoaded gibi.)
Erik Eidt

1
Redux'daki durum aslında güncellenir, asla değiştirilmez.
Andy

1
Partiye geç kaldığımı biliyorum, ancak Redct mimarisini .NET'e getiren React.NET adlı bir proje var .
SiberianGuy

Açısal projelerde ngrx / store yaklaşımını sevenler için .gr projeleri için ngrx / store'dan esinlenen NetRx.Store - devlet yönetimi vardır. Nuget'te de bulabilirsiniz . Ayrıca WPF projesinde MVVM desenli NetRx.Store
Vitalii Ilchenko

Yanıtlar:


8

Ne demek istediğini biliyorum. Temelde sorunu bir 'denetleyici' veya 'ana' görünüm modeli ekleyerek çözersiniz (psudocode'u özür)

yani

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;
    }
}

Bunu Arabulucu Deseni ile yaptığınızda, sınıfı bir Kontrolör olarak düşünüyorum. yani.

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;});
    }
}

Bu tür şeyler, 'akış mantığınızı' veya Etkinlik Düzenlemenizi bu üst düzey kalıcı sınıflara koymanıza ve VM kodunu açık tutmanıza olanak tanır. Kullanıcı 'SATIN AL' düğmesini tıklattığında 'değiştirmek isterseniz, sipariş' SiparişFlowController 'veya' OrderProcessVM 'içine bakmayı bildiğiniz şeyler gibi işlenir veya bunları adlandırmak istersiniz. BasketVM, PaymentVM, 3dSecureVM vb.

Dolayısıyla, 'sekme henüz hazır değil' özel örneğinizde,

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;
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.