web-dev-qa-db-fra.com

Comment gérer des vues complexes (composées de plusieurs parties) dans l'application Web MVC

Disons que je répète une application Web de blog utilisant un motif MVC. Layout typique de la page principale de l'application Blog est - une sorte d'index de poteau dans la partie principale, et de côté, des pièces d'addition, telles que la chronologie, le panneau de navigation des balises, le panneau d'abonnement, etc. Ces contrôles apparaissent également sur un seul Vue postale et peut apparaître sur d'autres points de vue que j'ai.

Ma question est - comment dois-je gérer ces panels de côté de mes vues et de contrôleurs. Je vois trois approches ici:

  1. Créez une grande classe de menuModel contenant toutes les informations requises pour rendant la vue S (l'index ou un poste unique). Ce cas, je pourrais faire de ces panneaux de côté une vue partielle et les appeler de la vue étant rendue faisant partie de cette grosse viewmodel. L'inconvénient est - je vais avoir le code de remplissage de la vue de la vue de la part de diverses méthodes de contrôleur, le code est dupliqué. Qui est assez mauvais.

  2. Créer une autre couche de rendu de visualisation. Dites, la couche la plus haute de la rendu recette une partie des parties HTML ou des fonctions allées. La couche sous cette "combinaison de couche partielle" ne donnerait que des vues partielles pour chaque panneau que je souhaite, inclure le contenu principal. L'inconvénient ici - Utilisation de la mémoire. La plupart des cadres modernes rend les HTML directement au flux de sortie, mais dans cette approche, des vues partielles seraient rendues dans des objets de chaîne en premier - ce qui conduit à la mémoire de mémoire.

  3. Utilisez quelque chose comme "Renderaction" de ASP.NET MVC, qui appelle une méthode de contrôleur à partir d'une vue. Je pense que c'est une pire solution de 3 donné, car elle laisse tomber une approche MVC.

La question n'est pas liée à un cadre spécifique, je souhaite comprendre la manière générale de faire des choses comme ça.

MISE À JOUR

Après une réponse donnée, j'ai découvert que l'article n'est pas clair. Do Mise à jour raisonnable ici:

Sous ViewModel Terme, je comprends un objet contenant toutes les données requises pour rendre une vue particulière.

Toutes les trois approches impliquent des vues partielles dans leur propre point de vue. Par exemple (en utilisant c # syntaxe):

class SinglePostViewModel {
  string Text {get;set;}
  string Title {get;set;}
  string Slug {get;set;}
  DateTime PublishedDate {get;set;}
  ...
}

class TagNavigationPanelViewModel {
  string TagText {get;set;}
  int PostsCount {get;set;}
}

class CalendarNavigationPanelViewModel {
  DateTime YearAndMonth {get;set;}
  int PostsCount {get;set;} 
}

Ma question est - comment combiner joliment ces vues partielles ensemble.

7
Hedin

Je vois une autre méthode que, sauf si j'ai mal compris votre message, n'a pas été mentionné:

La vue principale, post, aurait son modèle. Ce modèle consisterait à [~ # ~] uniquement [~ # ~ ~] Les propriétés nécessaires pour afficher ce message (author, title, body, etc.). Ensuite, chaque morceau de la vue post vous pouvez penser (timeline, tag navigation panel, subscribing panel, etc.), serait divisé en leur propre point de vue et chacun aurait son propre modèle. De cette façon, vous pouvez construire ces modèles de votre contrôleur lorsque vous en avez besoin.

Cela peut sembler comme une quantité inutile de travail supplémentaire pour les diviser comme ceci, mais il se prête au principe de responsabilité unique . Gardez chaque "vue/modèle" concentré sur lui-même afin qu'il puisse être réutilisé n'importe où, il est nécessaire.

Si vous sentez que votre code commence à dupliquer lui-même, ce qui pourrait en fonction de votre situation, vous devriez envisager d'écrire une sorte de "classe d'assistance". Cette classe d'assistance gérerait la totalité de l'accumulation de modèle en un seul endroit, et tout autre code en double serait dépouillé vers un appel de classe d'assistance.

1
ethorn10

Ce que je fais est une variation/combinaison de vos points 1 et 3. Je combine les images de vue dans une classe de conteneurs et utilisez-la comme une vue "principale". La passe les pièces comme des modèles aux partiels.

Suite à votre exemple, je créerais cette vueModel pour la page par défaut:

class DefaultViewModel {
  public List<SinglePostViewModel> Posts ...
  public TagNavigationPanelViewModel Tags ...
  public CalendarNavigationPanelViewModel Calendar ...
  ...
}

En défaut.cshtml

@model DefaultViewModel
...html for rendering the default page...


@Html.Partial("_TagNavigationPanel", Model.Tags)
...etc...

Dans _tagnavigationpanel.cshtml

@model TagNavigationPanelViewModel
...html+razor for rendering the tags...

Ensuite, suivez la même approche pour une seule page postale:

class SinglePostPageViewModel {
  public SinglePostViewModel Post ...
  // no tags in single view, for example..
  // public TagNavigationPanelViewModel Tags ...
  public CalendarNavigationPanelViewModel Calendar ...
  // But a list of related, perhaps?
  public List<RelatedPosts> RelatedPosts
  ...
}

Et construire votre point de vue (cshtml (s)) en conséquence

1
Lorenzo Dematté