Sollen wir view an eine Modelleigenschaft binden oder sollte ViewModel eine eigene haben ..?


21

Ich starte ein Projekt mit folgender technischer Umgebung: .Net 4.0, Entity Framework 4.0, WPF mit MVVM-Architektur

Ich habe viele Beispiele im Internet gesehen, einige Bücher mit dieser Umgebung. In einigen Beispielen hatten die Autoren diese Idee:

  1. Viemodel wird eine Instanz der Model-Klasse haben (Entity Framework Entity zB Person)
  2. Binden Sie die WPF-Ansichtssteuerelemente an die Eigenschaften von Model

Während einige Autoren taten:

  1. Viemodel legt alle Eigenschaften des Modells offen.
  2. Binden Sie die WPF-Ansichtssteuerelemente nicht direkt an das Modell, sondern an die Eigenschaften von ViewModel.

Ist es also eine gute Idee, die Ansicht Eigenschaften vom Modell binden zu lassen, anstatt das eigene Ansichtsmodell verfügbar zu machen? Oder was ist mehr bevorzugt?


Persönlich finde ich die Eigenschaften des Modells verfügbar zu machen, um eine gute Trennung von Datenebene und Logikebene zu erzielen.
Alex Hope O'Connor

Antworten:


25

Ich denke, viele Programmierer versuchen zuerst, die Verknüpfung direkt mit dem Modell zu übernehmen, aber meiner Erfahrung nach hat dies einige große Nachteile. Das primäre Problem ist , dass , wenn Ihr Entitätsmodell von NHibernate oder ähnliches beibehalten wird, dann, sobald die Ansicht des Modells Eigenschaft aktualisiert, dann NHibernate könnten diese Änderungen in der Datenbank bestehen. Das funktioniert nicht gut für Bearbeitungsbildschirme, die eine Schaltfläche Speichern / Abbrechen haben. Tatsächlich wird möglicherweise gewartet und alles als Batch beibehalten, aber wenn Sie das Modell ändern, wird die Änderung ausgeführt.

Sie könnten also immer noch mit der direkten Bindung an Modelleigenschaften auf schreibgeschützten Bildschirmen durchkommen, aber dann treten Inkonsistenzen auf.

Darüber hinaus implementieren die meisten Modelle keine INotifyPropertyChangedgeeigneten Bindungsziele, wenn sich der Status des Bildschirms nach der ersten Anzeige ändert.

Aufgrund der einfachen Autoeigenschaften empfehle ich, die Ansicht immer an das ViewModel und nicht an das Modell zu binden. Es ist konsistent, einfach und bietet Ihnen die größte Flexibilität, um zukünftige Änderungen zu unterstützen.


Ich mag deine Antwort. +1 für die Erwähnung von Edit / Save Screen. Aber dann wäre es entmutigend, die Eigenschaften zweimal zu schreiben - einmal im Modell und wieder im Ansichtsmodell. Dies würde auch die Entwicklungszeit verlängern. Halten Sie das für vertretbar?
Pravin Patil

9
@Pravin Patil - fwiw, jedes Mal, wenn ich diese Abkürzung genommen habe, habe ich mich später selbst verflucht, als ich zurückgehen und sie reparieren musste. Es ist vergleichsweise wenig Aufwand erforderlich, die Eigenschaften im ViewModel erneut zu implementieren, insbesondere wenn sie schreibgeschützt sind (da Sie automatisch implementierte Eigenschaften mit einem privaten Setter verwenden können). Tatsache ist, dass das Modell in den meisten Fällen eine andere Datenstruktur aufweist als das ViewModel. Lassen Sie die Flexibilität, das Modell zu ändern, ohne die Ansicht zu beeinträchtigen. Je weniger Sie die Ansicht ändern müssen, desto besser, da die Ansicht schwer zu testen ist.
Scott Whitlock

4
@Scott Whitlock: Ich entwickle seit zwei Jahren WPF-Anwendungen mit NHibernate und hatte nie irgendwelche Probleme, die direkt mit dem Modell zusammenhängen. Wenn sich eine Modelleigenschaft ändert, ist der Aufwand für die Änderung im Wesentlichen gleich, unabhängig davon, an was Sie gebunden sind. Und wenn ich später wirklich ein Routing im ViewModel selbst durchführen lassen muss, hat es sich nicht gelohnt, die Zeit zu investieren, bevor ich sie brauchte. Ich folge (noch) dem YAGNI-Ansatz und habe keine Schwierigkeiten. Ich denke, Sie und die anderen hier sind ein bisschen dogmatisch zu diesem Thema.
Falcon

16

Der Punkt von a ViewModelist, dass es ein Modell von ist View.

Sie sollten die ViewModelan View, nicht irgendwelche ModelEigenschaften (nicht direkt, sowieso) binden.


8

Ich finde beide Methoden akzeptabel

Die Bindung nur an das ViewModel ist der "MVVM-puristische" Ansatz und führt zu einer besseren Trennung zwischen den Schichten. Das Binden an das Modell ist normalerweise schneller und bequemer.

Sofern ich keinen guten Grund habe, die Ebenen vollständig zu trennen (Größe des Projekts, zukünftige Wartungsprobleme, Typ des Modells, mit dem ich arbeite, usw.), binde ich mich an das Modell.


7

Ich denke, was Sie sehen, ist ein Konzept namens Durchbinden. Wenn Ihr Modell eine Eigenschaft namens Name hat und Ihr Ansichtsmodell diese Eigenschaft ohne zusätzliche Bearbeitung oder Konvertierung verfügbar macht, können Sie sich so an das Modell durchbinden.

Pseudocode:

 {Binding: MyViewModel.MyModel.Name}

Dies geschieht, um die Anzahl der 'Fluff'-Eigenschaften im Ansichtsmodell zu verringern. Leider ist dies auch auf lange Sicht eine schlechte Idee. Das Konzept eines Ansichtsmodells besteht darin, sicherzustellen, dass die Ansicht keine Abhängigkeit vom Modell hat. Wenn Sie sich jetzt durchbinden, müssen Sie sicherstellen, dass Ihr Modell eine Eigenschaft mit dem Namen name enthält, da sonst die Implementierung unterbrochen wird.

Wenn Sie jedoch nur bis zum Ansichtsmodell binden, können Sie das Modell ändern, und die Ansicht würde es nie erfahren, da nur die Eigenschaft Name im Ansichtsmodell angezeigt wird.

Dies kann nun unter bestimmten Umständen verringert werden, wenn Ihr Modell auf einer Schnittstelle basiert. Wenn die Schnittstelle also ein IBaseDetails-Objekt hätte, das die Eigenschaft ModuleName enthüllt, dann könnten Sie:

Pseudocode:

 {Binding: MyViewModel.MyModel.ModuleName}

Solange eines der von Ihnen erstellten Modelle die IBaseDetails-Schnittstelle erfüllt, sollten Sie sich darüber im Klaren sein, dass dies ein Randfall ist, und im Allgemeinen ist es um 90% besser, Ihr Ansichtsmodell um alle Modelle zu wickeln, die es abdeckt.


2

Wenn Sie beim Versuch, von Modell -> ViewModel zu wechseln, starke Reibungsverluste feststellen, versuchen Sie etwas wie AutoMapper. Es beseitigt den Aufwand, der mit dem manuellen Kopieren von Eigenschaften verbunden ist.


1

Ich bin hierher gekommen, nur weil ich den gleichen Zweifel hatte und überzeugt war, dass ich mich immer an das Modell binden würde, anstatt an das Modell.

Nehmen Sie den Ansatz von Angular Reactive Form. Sie erstellen eine Formulargruppe mit einigen Informationen aus dem Modell anzeigen, müssen jedoch später auf das Formular zugreifen. Werte zum Abrufen der Werte und zum Kopieren der Werte in das Modell mithilfe von Auto-Mapper oder manuell. Ich denke, es gibt nichts Schöneres, als Eigenschaften im Ansichtsmodell zu verbergen. Nehmen wir beispielsweise an, ich habe eine Projektansichtsseite, auf der ich einen Projektnamen habe. Kundenname usw.

Es gibt eine Beziehung zwischen Projekt und Kunde, da ein Projekt einen Kunden hat. Auf dieser Ebene sollte mich diese Beziehung nicht interessieren. Ich muss nur den Projektnamen und den Clientnamen in der Ansicht visuell anzeigen, also füge ich 2 Eigenschaften in den Projektnamen und den Clientnamen des Ansichtsmodells ein, damit ich die Ansichtssteuerelemente an beide binde Ich werde mich später darum kümmern, diesen Eigenschaften im Code Werte zu geben, die dann von der Struktur des Modells abgeleitet werden.

Das gleiche könnte für die Aktualisierung des Modells im Fall von Speichern / Abbrechen gelten, da nichts mehr sauber ist.


Dieser Beitrag ist ziemlich schwer zu lesen (Textwand). Hätten Sie etwas dagegen bearbeiten sie in eine bessere Form ing?
18.

Auf geht's, Cheers.
Ivan Carmenates García
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.