Hilfe bei komplexen MVVM (mehrere Ansichten)

18

Ich benötige Hilfe beim Erstellen von Ansichtsmodellen für das folgende Szenario:

  1. Tiefe, hierarchische Daten
  2. Mehrere Ansichten für denselben Datensatz
  3. Jede Ansicht ist eine einzelne, sich dynamisch ändernde Ansicht, basierend auf der aktiven Auswahl
  4. Zeigen Sie abhängig vom Wert einer Eigenschaft verschiedene Arten von Registerkarten in einem Registersteuerelement an

Bildbeschreibung hier eingeben

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

Bildbeschreibung hier eingeben

Abbildung 2: Unterschiedlicher aktiver Raum. Mehrere Ansichten aktualisiert. Registersteuerelemente wurden basierend auf der Eigenschaft des Objekts geändert.

Bildbeschreibung hier eingeben

Abbildung 3: Unterschiedlicher Auswahltyp. Gesamte Ansicht ändert sich

Bildbeschreibung hier eingeben

Jayars
quelle
Übrigens, was ist eine Muli-Ansicht? Tippfehler?
JensG
"Muli view" war ein Tippfehler. Ich meinte unterschiedliche Ansichten für das gleiche Modell / Ansichtsmodell. Meine Frage war, sollte ich die gesamte Modellhierarchie für jede Ansicht umgestalten / umbrechen, damit jedes Ansichtsmodell nur das enthält, was die einzelne Ansicht benötigt? Oder sollte ich eine einzelne Ansichtsmodellhierarchie erstellen, die Eigenschaften aus allen Ansichten enthält? Seitdem ich diese Frage gestellt habe, hatte ich das (Un-) Glück, die Vor- und Nachteile der beiden herauszufinden, auf die harte Tour. Ich werde diesen Thread in Zukunft mit einer vollständigen Diagnose meiner Erfahrungen aktualisieren, wenn die Dinge nicht mehr so ​​hektisch sind.
Jayars
Denken Sie daran, dass eine Gestaltungsregel lautet, zuerst allgemeine Dinge zu zeigen und dann tief in die Details zu gehen. Sie erhalten eine helle Ansicht, und wenn der Benutzer tiefer geht, werden neue Ansichten angezeigt. Verwenden Sie daher kleine Ansichten mit voneinander getrenntem Ansichtsmodell. check this article design user interface
Csharls
@jsjslim Ich schauderte, als ich las "alle Hierarchien synchron halten". Ich vermute, Sie haben die Mehrfachansicht gewählt, und ich vermute, Sie haben es bereut (aber ich habe mich vorher geirrt). Können Sie uns für andere Leser, die möglicherweise die gleiche Frage haben, zumindest eine schnelle (ish) Antwort geben?
Guy Schalnat
2
@ guy-schalnat Die Mehrfachansicht war Voraussetzung. Mein Problem war, herauszufinden, wie man die Ansichtsmodelle erstellt. Das Projekt ist noch nicht abgeschlossen und ich kann keine Zeit finden, eine vollständige Analyse zu verfassen. Aber zusammenfassend: Ich hätte die Modellstruktur ignorieren und mich auf die Ansichten konzentrieren sollen. Die Komplexität, der ich begegnete, war selbst auferlegt: Ich wollte die Datenbindung von WPF so schlecht nutzen, dass ich fixiert wurde. Was ich am Ende gemacht habe, war gut, alter "copy / paste / refactor". Das endgültige Design, das sich herausstellte, war leichtgewichtig (geringe Wiederholung) und funktionierte vor allem. Wird in Zukunft eine vollständige Analyse schreiben.
Jayars

Antworten:

13

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

Bildbeschreibung hier eingeben

Oder ein Ansichtsmodell für jede Ansicht

Bildbeschreibung hier eingeben

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:

Bildbeschreibung hier eingeben

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:

  1. Hässlich / Arbeitscode> Schöner / nicht arbeitender Code
  2. Es ist einfacher, mehrere kleine Klassen zusammenzuführen, als eine große Klasse aufzulösen
Jayars
quelle
Ich wünschte, ich könnte das zweimal verbessern. Dies ist eine der klarsten Erklärungen für die Optionen, die ich gesehen habe.
Clever Human
3

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.

Euphorisch
quelle