MVVM: czy obiekt VM powinien wystawiać obiekt M bezpośrednio, czy tylko przez gettery delegujące do getterów M?

Najlepszym sposobem na wyjaśnienie jest przykład tak:

To jest model

public class Person 
{
    public int age;
    public string name;
}

To jest model widoku

public class PersonVM
{    
}

Moje pytanie brzmi:
czy maszyna wirtualna powinna wystawiać osobę na działanie szablonu danych lub hermetyzować właściwości modelu własnymi właściwościami?

Author: Jan Żankowski, 2009-07-11

4 answers

Model widoku powinien deklarować własne właściwości i ukrywać specyfikę modelu z widoku. Zapewnia to największą elastyczność i pomaga uniknąć wycieku problemów z typem modelu do klas modeli. Zazwyczaj klasy modelu widoku zawierają model według delegacji. Na przykład,

class PersonModel {
    public string Name { get; set; }
}

class PersonViewModel {
    private PersonModel Person { get; set;}
    public string Name { get { return this.Person.Name; } }
    public bool IsSelected { get; set; } // example of state exposed by view model

    public PersonViewModel(PersonModel person) {
        this.Person = person;
    }
}

Pamiętaj: model nie powinien wiedzieć nic o modelu widoku, który go konsumuje, a model widoku nie powinien wiedzieć nic o widoku, który go konsumuje. Widok nie powinien wiedzieć nic o modelach czających się w tle. W ten sposób zamyka model za właściwościami w modelu widoku.

 22
Author: jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-11 20:36:48

Nie ma ogólnej zgody na to pytanie. Na przykład było to jedno z otwartych pytań dotyczących MVVM sformułowanych przez Warda Bella tutaj :

Czy VM może oferować V rozpakowany M-obiekt (np. surowy Pracownik)? Lub musi M-obiekt ' s właściwości (jeżeli dopuszcza się nawet mieć właściwości!) być narażone wyłącznie przez powierzchnię Vm wrapper?

Główne zalety braku bezpośredniego eksponowania modelu w maszynie wirtualnej są:

  • Możesz użyć go jako "konwertera na sterydy", formując wartości modelu w wygodny sposób dla widoku

  • Możesz wprowadzić inne funkcjonalności związane z interfejsem użytkownika, takie jak komunikaty walidacji danych , undo redo ,..

Minusy to:

  • Będziesz musiał zduplikować dużo kodu, aby odsłonić wszystkie właściwości modeli w viewmodel.

  • Jeśli połączysz kontrolkę widoku z właściwość viewmodels, będziesz wysyłał zdarzenia z właściwości viewmodel. Ale co się stanie, jeśli właściwości modeli zmienią się z innego źródła niż setter viewmodel? Następnie musi powiadomić viewmodel, aby zakończyć z 2 Na PropertyChanged, jeden w modelu i jeden w viewmodel... dość skomplikowane!

Więc dla mnie poprawna odpowiedź brzmi: to zależy od twoich wymagań.

 38
Author: DaniCE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-23 10:56:37

Interesujące rozwiązanie tego problemu zaproponował Robert McCarter w MSDN Tom 25.

Http://msdn.microsoft.com/en-us/magazine/ff798279.aspx

Używa dynamicznego modelu widoku, aby zapewnić warstwę na wierzchu modelu, unikając proxy wszystkich właściwości modelu.

Jeśli Twoja przestrzeń problemowa nie wymaga wysokiej wydajności (dynamika nie powoduje uderzenia wydajności), jest to doskonałe rozwiązanie. Widok nie musi nic wiedzieć o modelu, ale model widoku nie musi zastępować właściwości, które są dostarczane " tak jak jest."W dowolnym momencie można dodać właściwości do modelu widoku, aby owinąć właściwości modelu bez modyfikowania widoku lub modelu. Przeczytaj artykuł, aby uzyskać więcej szczegółów.

 6
Author: Josh G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-05 14:52:39

Posiadanie ViewModel dla dowolnego modelu może być gorsze niż to. Co zrobić, jeśli masz hierarchiczną strukturę modelu, a nawet prosty zbiór? W takim przypadku będziesz musiał przejść przez wszystkie modele i zbudować instancję ViewModel dla modelu, a także zarejestrować zdarzenia notify-change lub inne zdarzenia. IMHO, to jest kompletnie szalone i nierozsądne. Jak powiedziała DaniCE, skończysz z dużą ilością kodu i wielkim bólem głowy.

 5
Author: Deepforest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-18 13:52:22