ASP.NET MVC 3: plantilla parcial frente a plantilla de visualización frente a plantilla de editor

303

Entonces, el título debería hablar por sí mismo.

Para crear componentes reutilizables en ASP.NET MVC, tenemos 3 opciones (podrían ser otras que no he mencionado):

Vista parcial:

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

Plantilla de editor personalizada:

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

Plantilla de visualización personalizada:

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

En términos de la Vista / HTML real, las tres implementaciones son idénticas:

@model WebApplications.Models.FooObject

<!-- Bunch of HTML -->

Entonces, mi pregunta es: ¿cuándo / cómo decides cuál de los tres usar?

Lo que realmente estoy buscando es una lista de preguntas que debe hacerse antes de crear una, para lo cual las respuestas se pueden usar para decidir qué plantilla usar.

Aquí están las 2 cosas que he encontrado mejor con EditorFor / DisplayFor:

  1. Respetan las jerarquías de los modelos cuando se representan ayudantes HTML (por ejemplo, si tiene un objeto "Bar" en su modelo "Foo", los elementos HTML para "Bar" se representarán con "Foo.Bar.ElementName", mientras que un parcial tendrá " ElementName ").

  2. Más robusto, por ejemplo, si tuviera List<T>algo de su ViewModel, podría usarlo @Html.DisplayFor(model => model.CollectionOfFoo), y MVC es lo suficientemente inteligente como para ver que es una colección y mostrar la única pantalla para cada elemento (en lugar de un Parcial, lo que requeriría un explícito para lazo).

También he oído que DisplayFor representa una plantilla de "solo lectura", pero no lo entiendo, ¿no podría arrojar un formulario allí?

¿Alguien puede decirme otras razones? ¿Hay una lista / artículo en algún lugar comparando los tres?

RPM1984
fuente
Los conceptos detrás del editor y las plantillas de visualización están claramente definidos en la documentación de asp.net mvc 2. Las plantillas son parciales que se adhieren a una convención específica. Las situaciones que hacen que las plantillas sean mejores o peores que los parciales antiguos dependen casi estrictamente de si la convención vale la pena o no en su aplicación.
Nick Larsen

Respuestas:

301

EditorForvs DisplayFores simple. La semántica de los métodos es generar vistas de edición / inserción y visualización / solo lectura (respectivamente). Úselo DisplayForal mostrar datos (es decir, cuando genera divisiones y tramos que contienen los valores del modelo). Úselo EditorForal editar / insertar datos (es decir, cuando genera etiquetas de entrada dentro de un formulario).

Los métodos anteriores están centrados en el modelo. Esto significa que tomarán en cuenta los metadatos del modelo (por ejemplo, podría anotar su clase de modelo con [UIHintAttribute]o [DisplayAttribute]y esto influiría en qué plantilla se elige para generar la interfaz de usuario para el modelo. También se usan generalmente para modelos de datos (es decir, modelos que representar filas en una base de datos, etc.)

Por otro lado, Partialestá centrado en la vista, ya que le preocupa principalmente elegir la vista parcial correcta. La vista no necesariamente necesita un modelo para funcionar correctamente. Simplemente puede tener un conjunto común de marcado que se reutiliza en todo el sitio. Por supuesto, muchas veces desea afectar el comportamiento de este parcial, en cuyo caso es posible que desee pasar a un modelo de vista apropiado.

No preguntaste sobre @Html.Actioncuál también merece una mención aquí. Se podría considerar como una versión más poderosa de Partialque ejecuta una acción secundaria del controlador y luego presenta una vista (que generalmente es una vista parcial). Esto es importante porque la acción secundaria puede ejecutar lógica empresarial adicional que no pertenece a una vista parcial. Por ejemplo, podría representar un componente del carrito de compras. La razón para usarlo es evitar realizar el trabajo relacionado con el carrito de compras en cada controlador de su aplicación.

En última instancia, la elección depende de qué es lo que está modelando en su aplicación. También recuerda que puedes mezclar y combinar. Por ejemplo, podría tener una vista parcial que llame al EditorForayudante. Realmente depende de cuál sea su aplicación y cómo factorizarla para alentar la máxima reutilización del código y evitar la repetición.

marcind
fuente
44
Esa es una gran respuesta, exactamente lo que estaba buscando. En realidad, confiaba en que vendrías a responder esto. :) Gracias Marcin.
RPM1984
¿Cómo utiliza las anotaciones para especificar una plantilla de visualización y una plantilla de editor para una sola propiedad?
stormwild
3
@stormwild usa la convención y nombra sus plantillas después del modelo al que se refieren (/Views/DisplayTemplates/MyModel.cshtml) o lo fuerza explícitamente con la anotación UIHint.
Tom Wayson el
¿Algún consejo para elegir para crear un asistente de "usuario registrado" reutilizable? Quiero crear estas vistas (y controladores) en un ensamblaje separado si es posible. También conocido como una forma de redistribuir entre varios equipos estos valiosos formularios / controladores mvc. (hemos creado una única forma de manejar el usuario / almacenamiento (servicios webapi) ... pero cada equipo está creando sus propias páginas mvc: <Gracias.
granadaCoder
¿Dónde guardas esas plantillas? ¿Necesito almacenarlos en Shared / EditorTemplates o es posible almacenarlos directamente en la carpeta del controlador actual (cuando los necesito solo allí)?
Santhos
15

Ciertamente, puede personalizar DisplayForpara mostrar un formulario editable. Pero la convención es para DisplayForser readonlyy EditorForser para editar. Cumplir con la convención asegurará que no importa lo que pases DisplayFor, hará el mismo tipo de cosas.

Robert Levy
fuente
2
No creo que haya realmente ninguna pregunta / duda sobre cuándo se deben usar plantillas de visualización frente a plantillas de editor. La verdadera pregunta parece ser cuándo debe usar plantillas vs parciales. Su respuesta se pierde por completo esto.
Joshua Hayes
19
@Joshua: creo que hubo alguna pregunta: "También escuché que DisplayFor presenta una plantilla de" solo lectura ", pero no lo entiendo, ¿no podría arrojar un formulario allí?"
Robert Levy
13

Solo para dar mi valor de 2c, nuestro proyecto está utilizando una vista parcial con varias pestañas jQuery, y cada pestaña representa sus campos con su propia vista parcial. Esto funcionó bien hasta que agregamos una función mediante la cual algunas de las pestañas compartían algunos campos comunes. Nuestro primer enfoque para esto fue crear otra vista parcial con estos campos comunes, pero esto se volvió muy complicado cuando se usa EditorFor y DropDownListFor para representar campos y menús desplegables. Para obtener los identificadores y nombres únicos, tuvimos que representar los campos con un prefijo dependiendo de la vista parcial principal que lo mostraba:

    <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>

Esto se puso bastante feo, así que decidimos usar Plantillas de editor en su lugar, lo que funcionó mucho más limpio. Agregamos un nuevo modelo de vista con los campos comunes, agregamos una plantilla de editor coincidente y renderizamos los campos usando la plantilla de editor desde diferentes vistas principales. La plantilla del editor representa correctamente los identificadores y los nombres.

En resumen, una razón convincente para que usemos plantillas de editor fue la necesidad de representar algunos campos comunes en varias pestañas. Las vistas parciales no están diseñadas para esto, pero las Plantillas del Editor manejan el escenario perfectamente.

Ciaran Bruen
fuente
1
Tuve un problema similar al usar pestañas y terminé usando el ítem BeginCollectionItem de Steve Sanderson que genera los identificadores de control únicos para usted: blog.stevensanderson.com/2010/01/28/…
Wilky
1

Utilice el _partialenfoque de vista si:

  1. Ver lógica céntrica
  2. Qué mantener todo el _partialHTML relacionado con la vista solo en esta vista. En el método de plantilla, deberá mantener algo de HTML fuera de la Vista de plantilla, como "Encabezado principal o cualquier borde / configuración externo".
  3. Quiere hacer una vista parcial con lógica (desde el controlador) usando URL.Action("action","controller").

Razones para usar la plantilla:

  1. ¿Quieres eliminar ForEach(Iterator). La plantilla es lo suficientemente buena como para identificar el Modelo como un tipo de lista. Lo hará de forma automática.
  2. Modelo de lógica céntrica. Si se encuentran varias vistas en la misma pantalla para la carpeta Plantilla, la representación dependerá del Modelo aprobado.
jitendra joshi
fuente
1

Otra diferencia que no se ha mencionado hasta ahora es que una vista parcial no agrega prefijos de modelo mientras que una plantilla sí. Aquí está el problema

erhan355
fuente