2009-07-11 5 views
27

najlepszym sposobem, aby wyjaśnić to z np tak:MVVM: Czy obiekt maszyny wirtualnej powinien bezpośrednio wystawiać obiekt M, czy tylko za pośrednictwem obiektów pobierających przekazujących do modułów pobierających M?

Jest to model

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

Jest to model widok

public class PersonVM 
{  
} 

moje pytanie brzmi:
powinny VM wystawiać do szablonu danych lub hermetyzować właściwości modelu własnymi właściwościami?

+0

W tych prostych scenariuszach nie ma żadnej korzyści z posiadania modelu widoku. Jeśli powiesz, że chciałeś zaimplementować funkcję cofania itd., To logika trafiłaby na VM i owinąłbyś właściwości modelu. – rolls

Odpowiedz

18

Model widoku powinien zadeklarować własne właściwości i ukryć specyfikację modelu z widoku. Zapewnia to największą elastyczność i pomaga zapobiegać przenikaniu problemów typu modelu do klas modeli. Zwykle klasy modelu widoku zawierają model poprzez delegację. 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 nic na temat modelu widoku, który zużywa go znać, a model widok nie powinien nic o widoku, który zużywa ją znać. Widok nie powinien wiedzieć nic o modelach czających się w tle. Dlatego obuduj model za właściwościami w modelu widoku.

+0

Klasa PersonViewModel ma publiczny konstruktor z parametrem PersonModel. Zatem widok musi znać model, aby utworzyć model widoku ... To nie jest mvvm. Konstruktor powinien być wewnętrzny lub przyjmować tylko ogólne parametry, takie jak ciąg lub cokolwiek, aby zainicjować model. –

+0

Powiedzmy, że zmieniasz wartość w modelu (poprzez interfejs użytkownika). W konsekwencji model zmienia również inne wartości (zależnie od tego). Czy mógłbyś następnie uruchomić OnPropertyChangedHandler i mieć maszynę wirtualną, a następnie zaktualizować jej własne właściwości? To jest to, co zrobiłem i działa dobrze, ale jestem na tym nowicjuszem i nie wiem, czy to jest zła praktyka. – rolls

+0

Powtórz powyższy komentarz. Ten artykuł wydaje się implementować dokładnie to, co zrobiłem. https://msdn.microsoft.com/en-us/magazine/ff798279.aspx – rolls

31

Nie ma ogólnej zgody na to pytanie. Przykładowo, to jeden z otwartych pytań o MVVM sformułowanych przez Warda Bell here:

jest VM mogą zaoferować v nieopakowanych M-obiekt (na przykład surowy pracownika)? A może właściwości obiektu M o wartości (jeśli dozwolone jest nawet, aby miały właściwości!), Były narażone na działanie wyłącznie przez powierzchnię owinera VM ?

Główne zalety nie bezpośrednio wystawiając model z VM są:

  • można go używać jako „konwerter na sterydach”, formatowanie wartości modelowych w wygodny sposób dla widoku

  • można wstrzykiwać inne Funkcjonalność związana z interfejsem użytkownika, jak data validation messages, undo redo ..

Minusy to:

  • trzeba będzie powielać dużo kodu, aby odsłonić wszystkie modele właściwości w ViewModel.

  • po powiązaniu kontrolki widoku z właściwością viewmodels, wyślesz właściwość "Zmienione zdarzenia" z widoku. Ale co się stanie, jeśli właściwość modeli zmieni się z innego źródła, innego niż model ustawiający widok? Następnie musi powiadomić viewmodel, aby zakończyć z 2 OnPropertyChanged, jeden w modelu i jeden w viewmodel ... dość skomplikowane!

Dla mnie poprawna odpowiedź: zależy od Twoich wymagań.

+1

jest proste rozwiązanie dla wad, spraw, aby model widoku był proxy, z całą funkcjonalnością, którą chcesz dodać. –

+0

To świetny przykład demonstrujący dobry czas na "owinięcie" modelu, a następnie wstrzyknięcie większej ilości funkcji na wierzch. – rolls

5

Posiadanie ViewModel dla dowolnego modelu może być gorsze niż to. Co jeśli masz hierarchiczną strukturę Modelu, a nawet prostą kolekcję? W takim przypadku będziesz musiał powtórzyć wszystkie modele i zbudować instancję ViewModel na model, a także zarejestrować zdarzenia zmiany powiadomień lub inne zdarzenia. IMHO, to jest kompletnie szalone i nierozsądne. Jak powiedział DaniCE, skończy się mnóstwo kodu i duży ból głowy.

+1

Zgadzam się z Tobą, co teraz? – Shimmy

+0

Jest to stosunkowo prosty proces do zawijania istniejącego drzewa modelu do maszyny wirtualnej. Stwórz narzędzie, które to zrobi lub jeszcze lepiej zbuduj na własną podstawową klasę VM. Tak, istnieje pewna dodatkowa złożoność związana z konfiguracją maszyn wirtualnych i powiązaniem ich z ich poglądami, ale warto. Wynikiem są elementy inteligentnego kodu na każdym poziomie drzewa wizualnego. Koniec z wyszukiwaniem drzewa wizualnego, aby znaleźć kogoś, kto będzie obsługiwał operację. –

+1

Nigdy nie znalazłem dobry sposób radzić sobie ze złożonymi operacjami na poszczególnych ListBoxItems bez wizualnego testowania trafień ... aż do MVVM. Po zbudowaniu hierarchii VM i nadaniu każdej wirtualnej maszynie odpowiednich referencji, elementy ListBoxItem mają wszystko, czego potrzebują do wykonywania własnych złożonych operacji. –

5

Ciekawym rozwiązaniem na ten został zaproponowany przez Roberta McCartera objętości MSDN 25.

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

Używa dynamicznego widoku modelu, aby zapewnić warstwę na wierzchu modelu unikając buforowania wszystkich Modelu nieruchomości.

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

+0

Lub użyj najlepszego z obu światów ... Zdefiniuj dynamiczną bazę Zobacz klasę modelu i niedynamiczną bazę Model widoku. Użyj niedynamicznych dla wysokiej wydajności modeli widoku i dynamicznej klasy bazowej dla wszystkich pozostałych. –

+0

pamiętaj, że DLR nie jest obsługiwany w Silverlight: "( Nienawidzę również właściwości proxy – Shimmy

+0

@Shimmy: To nie jest zaskakujące, Silverlight wciąż brakuje wielu wielkości WPF. –

Powiązane problemy