36 votes

ASP.NET MVC - Comment utiliser exactement les modèles de vue

Disons que j'ai une page qui permet l'édition d'un utilisateur de détails, j'ai donc un ViewModel comme ceci:

public class UserViewModel {
    public string Username { get; set; }
    public string Password { get; set; }
    public int ManagerId { get; set; }
    public string Category { get; set; }
}

Donc sur mon EditUser action que je peux avoir cette passé par le modèle de classeur et puis je peux la carte que pour le Modèle de Domaine:

public ActionResult EditUser(UserViewModel user) {
    ...

Néanmoins, la page qui affiche le formulaire doit également des détails tels qu'une liste des Gestionnaires et des Catégories de fournir des listes déroulantes pour ces champs. Il peut également afficher une liste des autres utilisateurs dans une barre latérale de sorte que vous pouvez basculer entre les différents utilisateurs du montage.

Alors j'ai un autre modèle de vue:

public class ViewUserViewModel {
    public UserViewModel EditingUser { get; set; }
    public IEnumerable<SelectListItem> Managers { get; set; }
    public IEnumerable<SelectListItem> Categories { get; set; }
    public IEnumerable<SelectListItem> AllUsers { get; set; }
}

Est-ce la bonne façon de le faire? Sont-ils à la fois les Modèles de Vue? Si oui, est-il une convention de nommage que je devrais utiliser afin que je puisse distinguer entre les machines virtuelles qui sont comme les modèles et les machines virtuelles qui ne contiennent que les données de la page?

Ai-je eu ce tort et à travers?

94voto

Chris Pratt Points 53859

"Modèle de vue" n'est qu'un modèle. Il n'y a rien de magique dans le nom, mais en général, toute la classe qui est passé à un point de vue (que ce soit pour un simple affichage des données ou à des fins de soumissions de formulaire) est désigné comme un "modèle de vue" et donné un nom comme FooViewModel ou FooVM à indiquer qu'il fait partie de cette "vue" de modèle de modèle.

Je ne veux pas aller trop philosophique sur vous, mais je crois qu'un peu de référence sur les modèles dans le jeu sera utile. ASP.NET MVC évidemment assez encourage un MVC (Modèle-Vue-Contrôleur) modèle architectural. Dans MVC le Modèle de conteneur pour l'application de la logique métier. Le Contrôleur est responsable du traitement de la demande, d'aller chercher le modèle, le rendu de la Vue avec ce modèle et de renvoyer une réponse. Cela ressemble à beaucoup de responsabilité mais en réalité, le cadre assure la plus grande partie de derrière les coulisses, les Contrôleurs sont généralement (et devraient) être très clair sur le code. Ils sont responsables pour le minimum de fonctionnalités au fil de tout ce. Enfin, il est responsable de la création de la couche d'INTERFACE utilisateur qui permet à l'utilisateur d'interagir avec les données dans le Modèle. Il n'est pas responsable pour les données lui-même, ni ne devrait être (ViewData/ViewBag est un assez gros violation d'ici, au moins autant que la façon dont il finit par être utilisé par les développeurs dans la pratique).

Donc, cela signifie que la majeure partie de la logique de l'application devrait être dans votre modèle, et qui est généralement une bonne chose. Toutefois, étant donné que le modèle est le havre de données de l'application, il obtient généralement persisté dans une base de données ou similaire. Qui crée des conflits d'intérêts que vous devez maintenant commencer à un équilibre entre ce que les données doivent être conservées et que les données ne devrait exister que pour la fin de l'affichage.

C'est là que les modèles de vue venir. MVVM (Model-View-Vue Modèle), un peu parallèle pattern MVC, reconnaît les problèmes inhérents à un modèle-à-règle-them-all approche. Je n'entrerai pas dans les détails ici, car MVC ne pas utiliser ce modèle. Cependant, la plupart des ASP.NET MVC développeurs ont coopté le Modèle de Vue de MVVM. Ce que vous retrouvez avec une base de données adossés à des entité (le modèle traditionnel) et puis, généralement, plusieurs modèles de vue qui représentent cette entité dans divers états. Cela permet à votre modèle pour contenir la logique d'entreprise qui est pertinent pour la persistance, tandis que le modèle de vue(s) contiennent la logique métier pertinents pour l'affichage, la création et la mise à jour de ce modèle.

J'ai dû abandonner un peu, mais le long et court, c'est que ce que vous faites est tout à fait acceptable. En fait, c'est une bonne pratique. Créer autant de modèles de vue que votre application a besoin, et de les utiliser pour stocker les données et la logique métier nécessaire pour votre point de vue. (Qui inclut des choses comme SelectLists. Ni votre contrôleur ni vue devriez avoir besoin de savoir comment créer un SelectList pour une liste déroulante.)

20voto

Mariusz Points 871

Comment je le faire en raccourci:

  1. Créer des ViewModel de la classe pour chaque formulaire sur la page, puis j'ai rendu ces classes avec PartialViews comme @{Html.RenderPartial("PartialName", Model.PartialModel);}.
  2. Si la page contient des choses comme le html metas je fais séparés de classe pour les metas et le mettre dans la section sur la page.
  3. Reste des cas comme "dois-je mettre cela dans des locaux séparés de la classe?", c'est votre jugement.

Ainsi, par exemple, vous avez la page qui a une sorte de connexion/s'inscrire bar ou un pop-up que ce soit.

public class SomePageViewModel
{
    public RegisterBarVM Register { get; set; }
    public LoginBarVM LoginBar { get; set; }

    public MetasVM Metas { get; set; }
    public string MaybePageTitle { get; set;}
    public string MaybePageContent { get; set;}

    [HiddenInput(DisplayValue = false)]
    public int IdIfNeeded { get; set; }

    public IEnumerable<SelectListItem> SomeItems {get; set;}
    public string PickedItemId { get;set; }
}

public class RegisterBarVM
{
    public string RegisterUsername {get;set;}
    public string RegisterPassword {get;set;}
    //...
}

public class LoginBarVM
{
    public string LoginUserame {get;set;}
    public string LoginPassword {get;set;}
    //...
}

//cshtml
@model yourClassesNamespace.SomePageViewModel
@{
    Html.RenderPartial("LoginBar", Model.LoginBar); //form inside
    Html.RenderPartial("RegisterBar", Model.RegisterBar); //form inside

    using(Html.BeginForm())
    {
        @Html.EditorFor(m => m.IdIfNeeded)
        @Hmtl.EditorFor(m => m.MaybePageTitle)
        @Hmtl.EditorFor(m => m.MaybePageContent)

        @Hmtl.DropDownListFor(m => m.PickedItemId, new SelectList(Model.SomeItems))

        <input type="submit" value="Update" />
    }
}

@section Metas {
    @{Html.RenderPartial("Meatas", Model.Metas}
}

À propos de l'éditeur de modèles de Brad Wilson Blog et tout simplement google ou chercher des piles de ressources à propos de l'affichage/l'éditeur de modèles et HtmlHelpers. Elles sont toutes très utiles pour la construction cohérente des sites web.

9voto

Jason Berkan Points 4606

Personnellement, je préfère mettre toutes les informations nécessaires pour le rendu de la page dans le ViewModel, comme c'est le but de ce Dernier à fournir toutes les données de la Vue. Donc, mon UserViewModel serait contiennent des propriétés de Managers, Categories et AllUsers et le contrôleur de remplir ces collections d'avant le passage de ce Dernier à la vue.

C'est essentiellement ce que vous avez fait - il supprime juste les extra ViewModel à partir de l'équation.

J'ai également vu d'autres programmeurs utilisent le ViewData pour envoyer les listes déroulantes de la vue, mais je n'aime pas que parce que ViewData n'est pas fortement typé, alors qu'un ViewModel est.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X