Potrzebuję pomocy w tworzeniu modeli widoku dla następującego scenariusza:
- Głębokie, hierarchiczne dane
- Wiele widoków dla tego samego zestawu danych
- Każdy widok jest pojedynczym, dynamicznie zmieniającym się widokiem, opartym na aktywnym zaznaczeniu
- W zależności od wartości właściwości wyświetl różne typy kart w kontrolce kart
Moje pytania:
Czy powinienem utworzyć reprezentację modelu widoku dla każdego widoku (VM1, VM2 itp.)?
1. Yes:
a. Should I model the entire hierarchical relationship? (ie, SubVM1, HouseVM1, RoomVM1)
b. How do I keep all hierarchies in sync? (e.g, adding/removing nodes)
2. No:
a. Do I use a huge, single view model that caters for all views?
Oto przykład jednego widoku
Rysunek 1: Zaktualizowano wiele widoków w oparciu o aktywny pokój. Kontrola karty powiadomień
Rysunek 2: Różne aktywne pomieszczenie. Zaktualizowano wiele widoków. Elementy sterujące tabulatorami zmieniono na podstawie właściwości obiektu.
Rysunek 3: Inny typ wyboru. Całe zmiany widoku
Odpowiedzi:
Aby odpowiedzieć na pytanie: Tak, każdy widok powinien mieć własny model widoku. Ale nie ma potrzeby modelowania całej hierarchii. Tylko to, czego potrzebuje widok.
Problem, który miałem z większością zasobów internetowych dotyczących MVVM:
W większości przykładów widok jest prawie odwzorowaniem modelu w stosunku 1 do 1. Ale w moim scenariuszu, w którym istnieją różne widoki dla różnych aspektów tego samego modelu, utknąłem między dwiema opcjami:
Jeden monolityczny model widoku używany przez wszystkie inne modele widoku
Lub jeden model widoku dla każdego widoku
Ale oba nie są idealne.
Model widokowy zorientowany na model (MVM), mimo niskiego poziomu duplikacji kodu, jest koszmarem do utrzymania
Model widoku zorientowany na widok (VVM) tworzy wysoce wyspecjalizowane klasy dla każdego widoku, ale zawiera duplikaty.
Ostatecznie zdecydowałem, że posiadanie jednej maszyny wirtualnej na widok jest łatwiejsze w utrzymaniu i kodowaniu, więc zdecydowałem się na podejście VVM.
Gdy kod działa, zacząłem refaktoryzować wszystkie typowe właściwości i operacje do jego obecnej, końcowej postaci:
W tej ostatecznej formie klasa wspólnego modelu widoku składa się z każdej VVM.
Oczywiście nadal muszę zdecydować, co jest uważane za wspólne / specjalistyczne. A gdy widok zostanie dodany / scalony / usunięty, to saldo się zmienia.
Ale fajną rzeczą jest to, że jestem teraz w stanie przesuwać członków w górę / w dół ze wspólnego do VVM i odwrotnie.
I krótka uwaga na temat synchronizacji obiektów:
Posiadanie modelu wspólnego widoku zajmuje się większością tego. Każda VVM może po prostu mieć odniesienie do tego samego modelu widoku wspólnego.
Zaczynam też od prostych metod wywołania zwrotnego i ewoluuję do zdarzenia / obserwatora, jeśli pojawi się potrzeba wielu słuchaczy.
W przypadku naprawdę skomplikowanych zdarzeń (tj. Nieoczekiwanych aktualizacji kaskadowych) przejdę na używanie Mediatora.
Nie unikam kodu, w którym dziecko ma odniesienie do swojego rodzica. Wszystko, żeby kod działał.
A jeśli pojawi się okazja do refaktoryzacji, skorzystam z niej.
Lekcje, których się nauczyłem:
źródło
Patrząc na twoje makiety, zdecydowanie polecam stworzenie hierarchii ViewModels i wielu małych widoków. I najprawdopodobniej będziesz musiał modelować całkiem sporo oryginalnej hierarchii.
Aby zachować synchronizację między ViewModels, użyj albo zdarzeń, albo miej właściwości między sobą między ViewModels. Synchronizacja między widokami i modelami ViewModels powinna być standardowymi właściwościami powiadamiającymi.
źródło