Ich benötige Hilfe beim Erstellen von Ansichtsmodellen für das folgende Szenario:
- Tiefe, hierarchische Daten
- Mehrere Ansichten für denselben Datensatz
- Jede Ansicht ist eine einzelne, sich dynamisch ändernde Ansicht, basierend auf der aktiven Auswahl
- Zeigen Sie abhängig vom Wert einer Eigenschaft verschiedene Arten von Registerkarten in einem Registersteuerelement an
Meine Fragen:
Soll ich für jede Ansicht (VM1, VM2 usw.) eine Ansichtsmodelldarstellung erstellen?
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?
Hier ist ein Beispiel für eine einzelne Ansicht
Abbildung 1: Mehrere Ansichten werden basierend auf dem aktiven Raum aktualisiert. Beachten Sie die Tab-Steuerung
Abbildung 2: Unterschiedlicher aktiver Raum. Mehrere Ansichten aktualisiert. Registersteuerelemente wurden basierend auf der Eigenschaft des Objekts geändert.
Abbildung 3: Unterschiedlicher Auswahltyp. Gesamte Ansicht ändert sich
Antworten:
Um die Frage zu beantworten, sollte jede Ansicht ein eigenes Ansichtsmodell haben. Es ist jedoch nicht erforderlich, die gesamte Hierarchie zu modellieren. Nur was die Aussicht braucht.
Das Problem, das ich mit den meisten Online-Ressourcen in Bezug auf MVVM hatte:
In den meisten Beispielen handelt es sich bei der Ansicht um eine beinahe 1-zu-1-Zuordnung des Modells. In meinem Szenario, in dem es unterschiedliche Ansichten für verschiedene Facetten desselben Modells gibt, stehe ich jedoch zwischen zwei Optionen fest:
Ein monolithisches Ansichtsmodell, das von allen anderen Ansichtsmodellen verwendet wird
Oder ein Ansichtsmodell für jede Ansicht
Beides ist aber nicht ideal.
Das modellorientierte Ansichtsmodell (MVM) ist trotz seiner geringen Codeduplizierung ein Albtraum
Das ansichtsorientierte Ansichtsmodell (VVM) erstellt für jede Ansicht hochspezialisierte Klassen, enthält jedoch Duplikate.
Am Ende entschied ich, dass eine VM pro View einfacher zu warten und zu programmieren ist, und entschied mich für den VVM-Ansatz.
Sobald der Code funktioniert, habe ich begonnen, alle gängigen Eigenschaften und Operationen in die aktuelle, endgültige Form umzugestalten:
In dieser endgültigen Form ist die gemeinsame Ansichtsmodellklasse in jeder VVM zusammengefasst.
Natürlich muss ich noch entscheiden, was als allgemein / spezialisiert gilt. Und wenn eine Ansicht hinzugefügt / zusammengeführt / gelöscht wird, ändert sich dieser Saldo.
Aber das Schöne daran ist, dass ich jetzt problemlos Up / Down-Mitglieder von Common zu VVM und umgekehrt pushen kann.
Und ein kurzer Hinweis zum Synchronisieren der Objekte:
Ein gemeinsames Ansichtsmodell erledigt das meiste. Jede VVM kann einfach einen Verweis auf dasselbe Common View-Modell haben.
Ich tendiere auch dazu, mit einfachen Callback-Methoden zu beginnen und mich zum Ereignis / Beobachter zu entwickeln, wenn das Bedürfnis nach mehreren Zuhörern entsteht.
Und für wirklich komplexe Ereignisse (dh unerwartete kaskadierende Aktualisierungen) würde ich auf die Verwendung eines Mediators umstellen.
Ich scheue mich nicht vor Code, bei dem ein Kind einen Rückverweis auf sein Elternteil hat. Alles, um den Code zum Laufen zu bringen.
Und wenn sich die Gelegenheit zur Umgestaltung ergibt, würde ich es nutzen.
Die Lektionen, die ich gelernt habe:
quelle
Mit Blick auf Ihre Modelle würde ich definitiv empfehlen, eine Hierarchie von ViewModels und viele kleine Ansichten zu erstellen. Und Sie werden höchstwahrscheinlich einiges von der ursprünglichen Hierarchie modellieren müssen.
Verwenden Sie Ereignisse oder Eigenschaften zwischen ViewModels, um die Synchronisierung zwischen ViewModels zu gewährleisten. Die Synchronisierung zwischen Ansichten und ViewModels sollte Standardeigenschaften für Benachrichtigungen sein.
quelle