Devrions-nous lier la vue à une propriété de modèle ou ViewModel devrait avoir sa propre propriété ..?

21

Je démarre un projet avec l'environnement technique suivant: .Net 4.0, Entity Framework 4.0, WPF avec MVVM Architecture

J'ai vu plein d'exemples sur le net, quelques livres avec cet environnement. Dans certains des exemples, les auteurs avaient cette idée:

  1. Viemodel aura une instance de la classe Model (Entity Framework Entity par exemple Person)
  2. Lier les contrôles de vue WPF aux propriétés du modèle

Alors que certains auteurs l'ont fait:

  1. Viemodel exposera toutes les propriétés du modèle.
  2. Liez les contrôles de vue WPF aux propriétés de ViewModel plutôt qu'au modèle directement.

Est-ce donc une bonne idée de laisser la vue lier les propriétés du modèle plutôt que le modèle de vue exposant les siennes? Ou lequel est le plus préféré?

Pravin Patil
la source
Personnellement, je trouve que l'exposition des propriétés du modèle entraîne une bonne séparation de votre couche de données et de vos couches logiques.
Alex Hope O'Connor

Réponses:

25

Je pense que beaucoup de programmeurs essaient d'abord de prendre le raccourci de liaison directement au modèle, mais d'après mon expérience, cela présente certains inconvénients majeurs. Le problème principal est que si votre modèle d'entité est persisté par NHibernate ou similaire, dès que la vue met à jour la propriété du modèle, NHibernate peut persister ces modifications dans la base de données. Cela ne fonctionne pas bien pour les écrans d'édition qui ont un bouton Enregistrer / Annuler. En fait, il peut choisir d'attendre et de tout conserver en tant que lot, mais l'idée est que lorsque vous modifiez le modèle, vous validez votre modification.

Ainsi, vous pouvez toujours vous passer de la liaison directe aux propriétés du modèle sur des écrans en lecture seule, mais vous aurez alors une incohérence.

De plus, la plupart des modèles ne sont pas implémentés INotifyPropertyChanged, ils peuvent donc ne pas être des cibles de liaison appropriées si l'état de l'écran change après l'affichage initial.

Étant donné la facilité des propriétés automatiques, je suggère de toujours lier la vue au ViewModel, pas au modèle. Il est cohérent, simple et vous offre la plus grande flexibilité pour prendre en charge les changements à l'avenir.

Scott Whitlock
la source
J'aime ta réponse. +1 pour mentionner Edit / Save Screen .. Mais alors il serait intimidant d'écrire les propriétés deux fois - une fois dans le modèle et à nouveau dans le modèle d'affichage. Cela augmenterait également le temps de développement. Pensez-vous qu'il soit justifié de le faire ...?
Pravin Patil
9
@Pravin Patil - fwiw, chaque fois que j'ai pris ce raccourci, je me suis maudit plus tard quand j'ai dû revenir en arrière et le réparer. Il y a relativement peu d'efforts pour réimplémenter les propriétés sur le ViewModel, surtout si elles sont en lecture seule (car vous pouvez utiliser des propriétés implémentées automatiquement avec un setter privé). Le fait est que, dans la plupart des cas, le modèle est une structure de données différente de celle du ViewModel. Laissez-vous la possibilité de modifier le modèle sans affecter la vue. Moins vous devez modifier la vue, mieux c'est, car la vue est difficile à tester.
Scott Whitlock
4
@Scott Whitlock: Je développe des applications WPF avec NHibernate depuis deux ans maintenant et je n'ai jamais eu aucun problème de liaison directe avec le modèle. En fait, lorsqu'une propriété de modèle change, c'est généralement le même effort pour le changement, indépendamment de ce à quoi vous êtes lié. Et quand j'ai vraiment besoin de faire un routage dans le ViewModel lui-même plus tard, alors cela ne valait pas la peine d'investir du temps avant d'en avoir besoin. Je suis (encore) l'approche YAGNI et je n'ai aucune difficulté. Je pense que vous et les autres ici êtes un peu dogmatiques sur cette question.
Falcon
16

Le point de a ViewModelest qu'il s'agit d'un modèle du View.

Vous devez lier le ViewModelà View, pas à des Modelpropriétés (pas directement, de toute façon).

Oded
la source
8

Je trouve les deux méthodes acceptables

Lier uniquement au ViewModel est l'approche "MVVM-puriste" et conduit à une meilleure séparation entre les couches. La liaison au modèle est généralement plus rapide et plus pratique.

À moins d'avoir une bonne raison de séparer complètement les couches (taille du projet, problèmes de maintenance futurs, type de modèle avec lequel je travaille, etc.), je me lie au modèle.

Rachel
la source
7

Je pense que ce que vous voyez est un concept appelé liaison, c'est-à-dire que si votre modèle a une propriété appelée nom et que votre modèle de vue expose cette propriété sans modification ou conversion supplémentaire, vous pouvez vous lier au modèle de sorte qu'il le soit.

Pseudo code:

 {Binding: MyViewModel.MyModel.Name}

Ceci est fait pour réduire la quantité de propriétés «Fluff» sur le modèle de vue, malheureusement c'est aussi une mauvaise idée à long terme. Le concept d'un modèle de vue consiste à garantir que la vue ne prend pas de dépendance par rapport au modèle. En vous liant, vous devez maintenant vous assurer que votre modèle contient une propriété appelée nom, sinon votre implémentation sera interrompue.

Cependant, si vous ne liez que le modèle de vue, vous pouvez modifier le modèle et la vue ne le saura jamais car elle ne verra que la propriété nommée Nom sur le modèle de vue.

Maintenant, cela peut être atténué dans certaines circonstances si votre modèle est basé sur une interface. Donc, si l'interface avait un IBaseDetails qui exposait la propriété ModuleName, vous pourriez:

Pseudo code:

 {Binding: MyViewModel.MyModel.ModuleName}

Tant que l'un des modèles que vous créez satisfait à l'interface IBaseDetails, votre or, sachez cependant qu'il s'agit d'un cas de bord et en général, vous êtes 90% toujours mieux pour enrouler votre modèle de vue autour de tous les modèles qu'il couvre.

DeanMc
la source
2

Si vous voyez beaucoup de friction essayer de passer de Modèle -> ViewModel, essayez quelque chose comme AutoMapper. Il supprime l'ennui associé aux propriétés de copie manuellement.

Bryan Boettcher
la source
1

Je suis arrivé ici juste parce que j'avais le même doute et je suis convaincu que je me lierais toujours pour voir le modèle plutôt que pour le modèle.

Adoptez l'approche de la forme réactive angulaire. Vous créez un groupe de formulaires à l'aide de certaines informations du modèle d'affichage, mais vous devez accéder ultérieurement au formulaire. Valeurs pour obtenir les valeurs et copier les valeurs dans le modèle en utilisant n'importe quel mappeur automatique ou manuel Je pense qu'il n'y a rien de plus beau que de se plier aux propriétés dans le modèle de vue, disons par exemple que j'ai une page de vue de projet où j'ai le nom du projet, nom du client, etc.

Il existe une relation entre le projet et le client puisqu'un projet a un client. Donc, à ce niveau, je ne devrais pas me soucier de cette relation.J'ai juste besoin d'afficher visuellement le nom du projet et le nom du client dans la vue.Je mets donc 2 propriétés dans le nom du projet du modèle de vue et le nom du client, donc je lie les contrôles de vue aux deux eux, plus tard, je m'inquiéterai de donner des valeurs à ces propriétés dans le code derrière puis de les prendre dans la structure du modèle.

Il en va de même pour la mise à jour du modèle en cas de sauvegarde / annulation il n'y a rien de plus propre.

Ivan Carmenates García
la source
ce post est assez difficile à lire (mur de texte). Pourriez-vous le modifier sous une meilleure forme?
moucher
Voilà, Cheers.
Ivan Carmenates García