2009-03-16 6 views
3

Ich habe eine richtige Barney bekommen meinen Kopf herum, wie alles zusammenpasst mit dem MVVM-Muster. In der Praxis scheint alles ganz einfach zu sein, aber wenn ich versuche, es zu implementieren, scheine ich verschiedene andere Regeln zu brechen, mit denen ich versuche zu kodieren.MVVM - Was sollte was enthalten? Was sollte was erstellen?

Nur als Nebenbemerkung, ich versuche, das Muster mit Flex, nicht Silverlight oder WPF zu implementieren, also wenn jemand mit guten Gründen kommen kann, warum dies nicht getan werden sollte, dann möchte ich sie hören .

Ich habe ein Problem, wo ich mehrere Ansichten habe. Manchmal muss ich zwei Ansichten auf der Seite gleichzeitig anzeigen; manchmal wechsle ich zurück zu einer einzigen Ansicht. In meinem normalen Flex-Gehirn hätte ich eine Hauptansicht mit einem Code-Behind, der alle meine anderen Ansichten enthielt (ebenso wie Code-Behinds). Diese Hauptansicht würde dann die anderen individuellen Ansichten wechseln.

Wenn ich versuche, dies in MVVM zu implementieren, versuche ich mich an die Prinzipien von MVVM zu halten, indem ich Bindung verwende, die meine Views von der ViewModels entkoppelt. Nehmen wir an, ich erstelle einen ViewModel für den anwendungsweiten Zustand und mein ApplicationView bindet an diese Daten und macht das gesamte Umschalten der Unteransichten.

Nun, wo soll ich meine View-Modelle für meine Subviews erstellen? Ich habe versucht, innerhalb der ApplicationView - das schien nicht richtig. Und dann habe ich versucht, außerhalb der Anwendungsansicht und Übergabe und Instanz davon in die ApplicationView und dann meine Untermodelle eine Bindung zu ihm. Fehle ich etwas? Keine dieser Methoden scheint zu dem Zweck zu passen, dies zu entkoppeln.

Alle guten Bücher oder Links, die dieses Problem erklären, würden sehr geschätzt werden.

Cheers, James

Antwort

7

Der Ansatz, auf den Sie sich beziehen, ist ViewModel-Komposition. Es enthält mehrere komplexe Ansichtsteile, die an ihre eigene ViewModel-Entität gebunden werden müssen. Bei diesem Ansatz wird ein Root-ViewModel mit Eigenschaften für jedes untergeordnete ViewModel erstellt. Dann ist die Stammansicht an das Stammsichtmodell gebunden, und jede Ansicht (ob angezeigt oder ausgeblendet) ist an die entsprechende Eigenschaft im Stamm-ViewModel gebunden.

Das Ansichtsmodell würde wie folgt aussehen:

public class RootViewModel 
{ 
    ChildViewModelA ChildA { get; set; } 
    ChildViewModelB ChildB { get; set; } 
} 

Die Ansicht würde wie folgt aussehen:

<Grid> 
    <ChildViewA DataContext="{Binding ChildA}" /> 
    <ChildViewB DataContext="{Binding ChildB}" /> 
</Grid> 

Sie auch diese in mich selbst zu ermöglichen, implementieren könnten einen aktiven Arbeitsbereich auswählen.

Das Ansichtsmodell würde wie folgt aussehen:

public class RootViewModel 
{ 
    public List<ViewModel> ChildWorkspaces { get; set; } 
    public ViewModel ActiveWorkspace { get; set; } 

    public RootViewModel() 
    { 
     ChildWorkspaces.Add(ChildViewModelA); 
     ChildWorkspaces.Add(ChildViewModelB); 
    } 
} 

Die Ansicht würde wie folgt aussehen:

<Grid> 
    <Grid.Resources> 
     <DataTemplate DataType="ChildViewModelA"> 
      <ChildViewA /> 
     </DataTemplate> 
     <DataTemplate DataType="ChildViewModelB"> 
      <ChildViewB /> 
     </DataTemplate> 
    </Grid.Resources> 
    <ContentControl Content="{Binding ActiveWorkspace}" /> 
</Grid> 

Diese in der entsprechenden visuellen Darstellung führen werden implizit ausgewählt basierend auf der Art der tatsächlichen Objekt in ActiveWorkspace gespeichert.

Verzeihung meine Antwort war in WPF. Ich versuchte mein Bestes, um nicht in der Syntax von allem gefangen zu werden :-)

Wie Sie sehen können, kann die Vielzahl von "ViewModel" mehrdeutig sein. Oft finden wir die Notwendigkeit, mehrere Unter-Entitäten zu konstruieren, um das ViewModel entsprechend zu strukturieren. Alle ViewModel-Entitäten befinden sich jedoch innerhalb des Stammobjekts View Model.

Wenn ich MVVM in WPF implementiere, ziehe ich es vor, abzuleiten, welches visuelle Element den Datenkontext implizit anwendet (wie in der späteren Hälfte dieser Antwort dargestellt). In komplexeren Szenarien verwende ich lieber einen DataTemplateSelector, um diese Entscheidung zu treffen. Aber in sehr einfachen Fällen können Sie DataContext entweder zwingend in C#/ActionScript oder deklarativ über Bindings anwenden.

Hoffe, das hilft!

+0

OK so denke ich, das ist meine Verwirrung aufgeklärt hat, wie ich nicht sicher war, ob die Ansichten, die einen Verweis auf das Ansichtsmodell enthalten sollte die ist, wie Sie in der ersten beschreiben z. Ich werde das für ein paar Tage offen lassen, um zu sehen, ob jemand anderes Kommentare abgibt, aber das ist im Grunde das, wonach ich gesucht habe. danke –

+0

Die einzigen "Verweise", die die Ansicht auf das ViewModel haben sollte, sollten deklarative Bindungen sein. Das Ziel bei MVVM ist, dass sowohl das View- als auch das ViewModel unabhängig voneinander agieren. – markti

3

Ich habe Varianten des MVVM Ansatz auf ein paar verschiedene Flex-Projekte verwendet gesehen, aber ich habe nicht einen Ansatz, der fühlt sich vollkommen richtig zu mir gesehen. Das heißt, ich denke, dass die Verwendung von Presentation Models das Testen in Flex erheblich vereinfacht. Daher bin ich mir ziemlich sicher, dass es mehr Anwendungen geben wird, die um dieses Muster herum entwickelt wurden.

Der einfachste Ansatz zur Implementierung von MVVM in Flex besteht darin, die einzelnen ViewModel s in der Anwendung Model/ModelLoactor zu platzieren. Die ModelLoactor enthält alle globalen Daten und dient auch als Accessor für alle ViewModels. ApplicationViews kann dann an ihre bestimmten ViewModel über die ModelLocator binden, während ViewModels sowohl durch Befehle und durch Bindungen an ihre Eltern aktualisiert werden kann. Ein Vorteil dieses Ansatzes besteht darin, dass die gesamte Datenlogik lokalisiert ist; natürlich könnte dies auch als ein Nachteil gesehen werden, mit der zentralen eine Berührung spröde aufgrund seiner hart codierten Referenzen auf alle ViewModels.

Ich habe sauberere Ansätze mit dem Mate-Framework gesehen. Mate ermöglicht eine viel dezentralere Injektion von ViewModels in die entsprechende ApplicationViews. (Ich nehme an, dies könnte auch mit Swiz erreicht werden, ich kenne diesen Rahmen nicht so gut). Mit Mate hat jeder ApplicationView seine ViewModel über eine Map injiziert. Was ist cool mit diesem Ansatz ist, wie ViewModels mit einer EventMap (die Mate-Version von FrontController) aktualisiert werden kann. Im Wesentlichen sendet Ihre ApplicationViews Ereignisse, die von einem oder mehreren EventMaps behandelt werden, und diese Karten können dann Änderungen an einem oder mehreren der ViewModels vornehmen.Dieser Ansatz ermöglicht eine Benutzergeste oder ein Ereignis von einem ApplicationView, um den Zustand von mehreren ViewModels auf einmal zu ändern. Da diese Logik in Mate EventMaps extrahiert wird, ist es außerdem sehr einfach zu ändern, wie Ereignisse behandelt werden oder welche ViewModels geändert werden. Der Hauptnachteil dieses Ansatzes besteht natürlich darin, dass Sie sich dazu verpflichten, Mate als Framework zu verwenden, was je nach den Anforderungen des Projekts möglicherweise keine Option ist.

Ich hoffe, dass hilft!