2010-10-29 15 views
6

Je me demande si c'est une bonne ou une mauvaise idée, en plaçant des choses comme une liste de pays dans ViewModel, pour lier à une liste déroulante? Par exemple sur la page d'inscription d'un site. J'ai eu l'impression qu'un ViewModel est supposé représenter une instance du formulaire rempli, mais je pense que je peux me tromper car j'ai vu d'autres personnes mettre des choses comme des listes dans leur ViewModel.meilleure pratique pour ce qui est dans un ViewModel

Ne serait-il pas préférable de le placer dans une classe statique et de l'appeler directement à partir de la vue?

Comme CommonData.ListCountries(); puis en utilisant Lambda pour convertir en liste d'éléments SelectList dans la vue Directement?

Répondre

9

Comme vous l'avez compris, il existe plusieurs façons d'atteindre votre objectif. Alors que le MVC design pattern encourage certaines organisations d'applications à organiser vos modèles, vues et contrôleurs, c'est une question de préférence. Scott Allen discute de sa préférence pour traiter avec ASP.NET MVC drop down lists dans un article de blog. Scott utilise une méthode d'extension pour convertir un énumérable d'un type complexe en un IEnumerable<SelectListItem> sur son modèle. Il décrit ensuite qu'après publication, ASP.NET MVC ne renvoie pas le IEnumerable<SelectListItem> qu'il a envoyé à la vue, mais uniquement la valeur sélectionnée par l'utilisateur. Il suggère ensuite que l'utilisation de deux modèles peut simplifier les choses.

Ceci est une description raisonnable de ce que j'appelle ViewModels et FormModels. Un ViewModel transporte les données d'affichage vers la vue et un FormModel est utilisé pour transporter les données collectées vers une action du contrôleur. Pour expliquer davantage:

  • Les ViewModels contiennent des données qui aident à afficher les vues. En organisant mes ViewModels de cette façon, je peux placer toutes les informations nécessaires pour afficher une vue particulière dans un modèle associé. Cela m'empêche d'utiliser ViewData pour tout ce qui n'est pas vraiment temporaire.
  • Les modèles de formulaire sont utilisés pour rassembler les entrées utilisateur. FormModels (presque) ne contient jamais de références à d'autres types complexes et sont constitués de primitives, de DateTimes et de chaînes.

Dans les deux cas, j'ai une règle stricte à never reuse a model for a different view. Le fait que vos modèles soient étroitement alignés sur les vues utilisées pour les rendre rend vos vues plus faciles à écrire. Vous n'avez pas à vous soucier de choses comme les méthodes statiques, car vos modèles doivent transporter des données vers leurs vues associées sous une forme facile à rendre. Des outils tels que AutoMapper peuvent aider à "aplatir" les objets de domaine dans des modèles à des fins d'affichage.

Pour la caisse de lecture supplémentaire: ASP.NET MVC terminology is tripping me up - why 'ViewModel'?

+0

Merci pour l'explication. Mais, si je n'utilise pas AJAX, quelle est la manière la plus propre d'afficher les erreurs sur le formulaire et de relier de nouveau les listes déroulantes? Je ne peux pas vraiment créer une nouvelle instance de mon modèle de vue, car elle contient un formulaire partiellement rempli, mais j'ai encore besoin de recréer la liste des pays pour revenir à la vue la deuxième fois. – lahsrah

+0

lahsrah: J'ai créé la méthode .populate() pour viewmodel et j'appelle cette méthode du contrôleur et son menu déroulant de remplir seulement, d'autres propriétés sont préservées du formulaire soumettre – Muflix

3

Quelles que soient les données dont votre vue a besoin, placez-la dans le ViewModel. De la façon dont je le vois, une fois que votre vue passe par le processus de rendu, elle devrait avoir toutes les informations dont elle a besoin à partir du modèle auquel elle est liée.

Si vous commencez à utiliser des méthodes auxiliaires, la vue "revient au contrôleur" dans un sens. Les méthodes d'extension/d'assistance sont correctes pour le formatage, etc., mais elles ne doivent pas appeler via le modèle.

N'oubliez pas, vous avez également ViewData (fondamentalement HttpContext.Current.Items, lives for single request), qui est un mécanisme de stockage léger qui peut être utilisé pour partager des données entre des vues partielles (par exemple).

+0

ok, alors comment puis-je gérer le cas où il y a des erreurs de validation sous la forme et le ViewModel doit être repassé dans l'action originale pour afficher le formulaire rempli parially, je aurait besoin de récupérer la liste à partir de la base de données. Dans ce cas, est-ce une bonne idée d'ajouter une méthode Populate sur le modèle de vue pour re-peupler ces listes déroulantes avant de le renvoyer à la vue, donc je ne remplis pas les listes déroulantes à deux endroits? – lahsrah

+2

Non, ce n'est pas une bonne idée. ViewModel devrait être de simples mécanismes de stockage pour conserver des données, et non pour les récupérer. Il ne devrait avoir que des propriétés (en général). Rappelez-vous, ce ne sont pas des formulaires Web. Il n'y a pas de ViewState, vos demandes devraient être sans état. Si, après avoir envoyé votre formulaire, vous avez encore besoin de données, allez-y à nouveau et définissez la valeur dans ViewModel. Les erreurs de validation doivent être gérées par l'état du modèle. Jetez un oeil à quelques-uns des vids/tutoriels sur www.asp.net/mvc – RPM1984

+0

Mieux encore que de réécrire les données est en train de faire des messages de formulaire AJAX et laisser le client (par exemple Javascript) décider où rediriger la page après un succès ou un message d'erreur est retourné. – Ryan