2009-03-16 5 views
3

Je vais avoir une bonne idée de la façon dont tout se combine en utilisant le modèle MVVM. Tout cela semble assez simple dans la pratique, mais en essayant de l'implémenter, il semble que je viole d'autres règles que j'essaie de coder. Juste comme une remarque, j'essaye d'implémenter le modèle utilisant Flex, pas Silverlight ou WPF, ainsi si n'importe qui peut venir avec de bonnes raisons pourquoi ceci ne devrait pas être fait, alors j'aimerais les entendre .MVVM - ce qui devrait contenir quoi ... ce qui devrait créer quoi

J'ai un problème où j'ai plusieurs vues. Parfois, je dois afficher deux vues sur la page en même temps; parfois je retourne à une seule vue. Dans mon cerveau normal de Flex j'aurais une vue principale avec un code-derrière qui a contenu toutes mes autres vues (également avec des derrière de code). Cette vue principale ferait alors la commutation des autres vues individuelles. Lorsque j'essaie de l'implémenter dans MVVM, j'essaie de m'en tenir aux principes de MVVM en utilisant la liaison qui sépare mon Views de ViewModels. Disons que je crée un ViewModel pour un état à l'échelle de l'application et mon ApplicationView se lie à ces données et effectue toute la commutation des sous-vues.

Maintenant, où dois-je créer mes modèles de vue pour mes sous-vues? J'ai essayé dans le ApplicationView - cela n'a pas semblé juste. Et puis j'ai essayé en dehors de la vue de l'application et en passant et l'instance de celui-ci dans le ApplicationView et puis mes sous-modèles une liaison à elle. Est-ce que je manque quelque chose? Aucune de ces méthodes ne semble aller dans le sens d'essayer de découpler cela.

Tous les bons livres ou des liens qui expliquent ce problème seraient très appréciés.

Cheers, James

Répondre

7

L'approche à laquelle vous faites référence est la composition ViewModel. C'est là où vous avez plusieurs parties de vue complexes qui doivent se lier à leur propre entité ViewModel. L'approche implique la construction d'un ViewModel racine avec des propriétés pour chaque ViewModel enfant. Ensuite, la vue racine est liée au modèle de vue racine et chaque vue (qu'elle soit affichée ou réduite) est liée à la propriété correspondante sur le ViewModel racine.

Le ViewModel ressemblerait à ceci:

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

La vue ressemblerait à ceci:

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

Vous pouvez également mettre en œuvre cela en loin pour vous permettre de sélectionner un espace de travail actif.

Le ViewModel ressemblerait à ceci:

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

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

La vue devrait ressembler à ceci:

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

Cela se traduira par la représentation visuelle appropriée étant implicitement sélectionné en fonction du type du réel objet stocké dans ActiveWorkspace. Pardon ma réponse était dans WPF.

J'ai essayé de mon mieux de ne pas être pris dans la syntaxe de tout cela :-)

Comme vous pouvez le voir la pluralité de "ViewModel" peut être ambiguë. Souvent, nous trouvons la nécessité de construire plusieurs sous-entités pour structurer le ViewModel de manière appropriée. Mais toutes les entités ViewModel se trouvent quelque part dans l'objet View View du modèle racine. Lorsque j'implémente MVVM dans WPF, je préfère déduire quel élément visuel appliquer implicitement le contexte de données (comme illustré dans la moitié suivante de cette réponse). Dans des scénarios plus complexes, je préfère utiliser un DataTemplateSelector pour effectuer cette décision. Mais dans des cas super simples, vous pouvez explicitement appliquer DataContext soit impérativement en C#/ActionScript, soit de manière déclarative à travers des bindings.

Espérons que cela aide!

+0

OK donc je pense que cela a éclairci ma confusion que je ne sais pas si les vues doivent contenir une référence au modèle de vue qui est comment vous décrivez dans le premier exemple. Je vais laisser cela ouvert pendant quelques jours pour voir si quelqu'un d'autre commente mais c'est fondamentalement ce que je recherchais. merci –

+0

Les seules "références" que la vue devrait avoir à ViewModel devraient être des liaisons déclaratives. L'objectif de MVVM est que la View et le ViewModel soient agnostiques les uns des autres. – markti

3

j'ai vu des variantes de l'approche MVVM utilisée sur deux différents projets Flex, mais je n'ai pas vu une approche qui se sent parfaitement raison de moi. Cela dit, je pense que l'utilisation de Presentation Models rend les tests dans Flex beaucoup plus faciles, donc je suis presque sûr qu'il y aura plus d'applications conçues autour de ce modèle.

L'approche la plus simple que j'ai vu pour implémenter MVVM dans Flex est de placer les ViewModel individuels dans l'application Model/ModelLoactor. Le ModelLoactor contient des données globales et sert également d'accesseur à tous les ViewModels. ApplicationViews peut ensuite se lier à leur ViewModel par l'intermédiaire du ModelLocator, tandis que ViewModels peut être mis à jour à la fois via des commandes et via des liaisons à leur parent ModelLocator. Un avantage de cette approche est que toute la logique de données est localisée; bien sûr, cela pourrait également être considéré comme un inconvénient, avec le ModelLocator central étant un contact fragile en raison de ses références codées en dur à tous ViewModels.

J'ai vu des approches plus propres travailler en utilisant le framework Mate. Mate permet une injection beaucoup plus décentralisée de ViewModels dans le ApplicationViews approprié. (Je suppose que cela pourrait aussi être accompli avec Swiz, je ne suis pas aussi familier avec ce cadre). Avec Mate, chaque ApplicationView a son ViewModel injecté via une carte. Ce qui est cool avec cette approche est comment ViewModels peut être mis à jour en utilisant un EventMap (la version Mate d'un). Essentiellement, votre ApplicationViews distribuera les événements qui sont gérés par un ou plusieurs EventMaps, et ces cartes peuvent ensuite apporter des modifications à un ou plusieurs des ViewModels.Cette approche permet à un utilisateur un geste ou un événement d'un ApplicationView de changer l'état de plusieurs ViewModels à la fois. De plus, comme cette logique est extraite dans le EventMaps de Mate, il est très facile de changer la façon dont les événements sont traités ou quels sont les changements ViewModels. Bien sûr, l'inconvénient majeur de cette approche est que vous vous engagez à utiliser Mate comme cadre, ce qui peut ne pas être une option en fonction des exigences du projet.

J'espère que cela aide!

Questions connexes