web-dev-qa-db-fra.com

ASP.NET MVC 3 - Modèle d'affichage vs partiel vs modèle d'édition

Ainsi, le titre devrait parler pour lui-même.

Pour créer des composants réutilisables dans ASP.NET MVC, nous avons 3 options (par exemple d’autres que je n’ai pas mentionnées):

Vue partielle:

@Html.Partial(Model.Foo, "SomePartial")

Modèle d’éditeur personnalisé:

@Html.EditorFor(model => model.Foo)

Modèle d'affichage personnalisé:

@Html.DisplayFor(model => model.Foo)

En termes de View/HTML, les trois implémentations sont identiques:

@model WebApplications.Models.FooObject

<!-- Bunch of HTML -->

Donc, ma question est - quand/comment décidez-vous lequel des trois utiliser?

Ce que je recherche vraiment, c’est une liste de questions à vous poser avant de créer une question, pour lesquelles les réponses peuvent être utilisées pour choisir le modèle à utiliser.

Voici les 2 choses que j'ai trouvées mieux avec EditorFor/DisplayFor:

  1. Ils respectent les hiérarchies des modèles lors du rendu des aides HTML (par exemple, si vous avez un objet "Bar" sur votre modèle "Foo", les éléments HTML pour "Bar" seront rendus avec "Foo.Bar.ElementName", tandis qu'un partiel aura " ElementName ").

  2. Plus robuste, par exemple si vous avez un List<T> de quelque chose dans votre ViewModel, vous pouvez utiliser @Html.DisplayFor(model => model.CollectionOfFoo), et MVC est assez intelligent pour voir sa collection et afficher l’affichage unique de chaque élément (par opposition à partiel, ce qui nécessiterait une boucle for explicite).

J'ai aussi entendu que DisplayFor rendait un modèle "en lecture seule", mais je ne comprends pas cela - pourrais-je jeter un formulaire dessus?

Quelqu'un peut-il me dire d'autres raisons? Existe-t-il une liste/un article quelque part comparant les trois?

302
RPM1984

EditorFor vs DisplayFor est simple. La sémantique des méthodes consiste à générer (respectivement) les vues édition/insertion et affichage/lecture seule. Utilisez DisplayFor lors de l’affichage des données (c’est-à-dire lorsque vous générez des divs et étendues contenant les valeurs du modèle). Utilisez EditorFor lors de l’édition/insertion de données (c’est-à-dire lorsque vous générez des balises d’entrée dans un formulaire).

Les méthodes ci-dessus sont centrées sur le modèle. Cela signifie qu'ils prendront en compte les métadonnées du modèle (par exemple, vous pouvez annoter votre classe de modèle avec [UIHintAttribute] ou [DisplayAttribute] et cela influera sur le modèle choisi pour générer l'interface utilisateur du modèle. également généralement utilisé pour les modèles de données (c'est-à-dire des modèles représentant des lignes dans une base de données, etc.)

D'autre part, Partial est centré sur la vue en ce sens que vous êtes principalement préoccupé par le choix de la vue partielle correcte. La vue n'a pas nécessairement besoin d'un modèle pour fonctionner correctement. Il peut simplement avoir un ensemble commun de balises qui est réutilisé sur tout le site. Bien entendu, vous souhaitez souvent modifier le comportement de ce partiel, auquel cas vous pouvez souhaiter transmettre un modèle de vue approprié.

Vous n'avez pas posé de question sur @Html.Action qui mérite également une mention ici. Vous pourriez considérer cela comme une version plus puissante de Partial dans la mesure où il exécute une action enfant du contrôleur, puis affiche une vue (qui est généralement une vue partielle). Cela est important car l'action enfant peut exécuter une logique métier supplémentaire qui n'appartient pas à une vue partielle. Par exemple, cela pourrait représenter un composant du panier. Son utilisation a pour but d'éviter d'effectuer le travail lié au panier dans chaque contrôleur de votre application.

En fin de compte, le choix dépend de ce que vous modélisez dans votre application. Rappelez-vous également que vous pouvez mélanger et assortir. Par exemple, vous pouvez avoir une vue partielle qui appelle l’assistant EditorFor. Cela dépend vraiment de la nature de votre application et de la manière de la factoriser pour encourager une réutilisation maximale du code tout en évitant les répétitions.

299
marcind

Vous pouvez certainement personnaliser DisplayFor pour afficher un formulaire modifiable. Mais la convention veut que DisplayFor soit readonly et EditorFor soit à éditer. Si vous vous en tenez à la convention, peu importe ce que vous passerez dans DisplayFor, vous obtiendrez le même genre de chose.

15
Robert Levy

Juste pour donner une valeur de 2c, notre projet utilise une vue partielle avec plusieurs onglets jQuery, et chaque onglet rend ses champs avec sa propre vue partielle. Cela a bien fonctionné jusqu'à ce que nous ajoutions une fonctionnalité permettant à certains onglets de partager certains champs communs. Notre première approche consistait à créer une autre vue partielle avec ces champs communs, mais cela devenait très difficile à utiliser avec EditorFor et DropDownListFor pour le rendu des champs et des listes déroulantes. Pour que les identifiants et les noms soient uniques, nous avons dû restituer les champs avec un préfixe en fonction de la vue partielle parent qui le rendait:

    <div id="div-@(idPrefix)2" class="toHide-@(idPrefix)" style="display:none">
    <fieldset>
        <label for="@(idPrefix).Frequency">Frequency<span style="color: #660000;"> *</span></label>

        <input name="@(idPrefix).Frequency"
               id="@(idPrefix)_Frequency"
               style="width: 50%;"
               type="text"
               value="@(defaultTimePoint.Frequency)"
               data-bind="value: viewState.@(viewStatePrefix).RecurringTimepoints.Frequency"
               data-val="true"
               data-val-required="The Frequency field is required."
               data-val-number="The field Frequency must be a number."
               data-val-range-min="1"
               data-val-range-max="24"
               data-val-range="The field Frequency must be between 1 and 24."
               data-val-ignore="true"/>

        @Html.ValidationMessage(idPrefix + ".Frequency")

        ... etc

    </fieldset>
</div>

Cela devenait assez moche alors nous avons décidé d'utiliser plutôt les modèles de l'éditeur, ce qui a fonctionné beaucoup plus propre. Nous avons ajouté un nouveau modèle de vue avec les champs communs, ajouté un modèle d'éditeur correspondant et rendu les champs à l'aide du modèle d'éditeur à partir de différentes vues parent. Le modèle d'éditeur affiche correctement les identifiants et les noms.

En bref, une raison impérieuse pour laquelle nous utilisions des modèles d’éditeur était la nécessité de rendre certains champs communs dans plusieurs onglets. Les vues partielles ne sont pas conçues pour cela, mais les modèles d'éditeur gèrent parfaitement le scénario.

13
Ciaran Bruen

Utilisez l’approche vue _partial si:

  1. Voir la logique centrique
  2. Que conserver tout le code HTML associé à la vue _partial dans cette vue uniquement. Dans la méthode du modèle, vous devrez conserver du code HTML en dehors de la vue Modèle, comme "En-tête principal ou toute bordure/paramètres extérieurs.
  3. Veut rendre une vue partielle avec une logique (à partir du contrôleur) en utilisant URL.Action("action","controller").

Raisons d'utiliser le modèle:

  1. Voulez-vous supprimer ForEach(Iterator). Le modèle est suffisant pour identifier le modèle comme un type de liste. Il le fera automatiquement.
  2. Logique centrée sur le modèle. Si plusieurs vues se trouvent dans le même dossier displayfor Template, le rendu dépendra du modèle passé.
1
jitendra joshi

Une autre différence qui n’a pas été mentionnée jusqu’à présent est qu’une vue partielle n’ajoute pas de préfixe de modèle, alors qu’un modèle ne le fait Ici est le problème

1
erhan355