El estándar MVC ejemplo la extracción de un elemento con la correspondiente Plantilla de Vista es:

Html.DisplayFor(m => m.Fecha)

Si el Modelo de objeto tiene una propiedad denominada Fecha de tipo DateTime, este devuelve una cadena con el código HTML de la Pantalla/DateTime.ascx plantilla.

Suponga que usted quiere hacer lo mismo, pero no podía usar con establecimiento inflexible de tipos de la versión que usted no sabe el Modelo del tipo de Vista en tiempo de compilación. Utilice los mayores:

Html.Mostrar(«Fecha»);

Así que aquí está la parte difícil.

Supongamos que el Modelo es IEnumerable. Usted no sabe lo que esos objetos están en tiempo de compilación, pero en tiempo de ejecución pasan a ser objetos con una Fecha de tipo DateTime, de nuevo, como:

public class ModelClass
{
    public DateTime Date { get; set; }
}

Ahora supongamos que usted quiere que su Vista para iterar a través de esos objetos y representar cada uno. Si todo lo que importaba era el valor que usted podría hacer esto:

<%
StringBuilder sb = new StringBuilder();
foreach(object obj in (IEnumerable<object>)Model)
{
    Type type = obj.GetType();

    foreach(PropertyInfo prop in type.GetProperties())
    {
        //TODO: Draw the appropriate Display PartialView/Template instead
        sb.AppendLine(prop.GetValue(obj, null).ToString());
    }
}
%>
<%= sb.ToString() %>

Estoy, obviamente, tomar algunos atajos para mantener este ejemplo se centró.

Aquí está el punto – ¿cómo puedo cumplir que TODO lo que he escrito para mí mismo? Yo no sólo quiero obtener el valor – quiero llegar muy bien que en el formato de Html.Mostrar(«Fecha»). Pero si acabo de llamar a Html.Mostrar(«Fecha»), inspecciona el Modelo, que es un IEnumerable, para una propiedad denominada Fecha, que por supuesto no tiene. Html.La pantalla no tomar un objeto como argumento para utilizar como Modelo (como Html.Mostrar(obj, «Fecha»), y de todas las clases y métodos que puedo encontrar que se encuentran por debajo parecen ser interno, así que no puedo modificar, y llamar a ellos directamente.

Debe haber alguna manera simple de lograr lo que yo estoy tratando de hacer, pero me parece que no puede encontrar.

Sólo para asegurarse de que estoy siendo claro – he aquí un ejemplo del código de DateTime.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime>" %>
<%= Model.ToString("MM/dd/yyyy") %>

Y así, idealmente, la salida desde este punto de Vista que puede tomar cualquier Modelo, pero en este caso una lista de 3 de estos ModelClass objetos de arriba, sería:

11/10/2001
11/10/2002
11/10/2003

Debido a que el código se encuentra la Pantalla PartialView para DateTime y la hacen apropiada para cada uno.

Así – ¿cómo puedo cumplir con la tarea?

OriginalEl autor Chris Moschini | 2010-10-19

2 Comentarios

  1. 8

    Tener una mirada en el código de la plantilla en este excelente post de Phil Haack. Que parece acercarse a lo que usted está buscando: http://haacked.com/archive/2010/05/05/asp-net-mvc-tabular-display-template.aspx

    Wow, excelente. Creo que esta es una gran respuesta, pero hay una gran falla en el código – suponga que usted desea dibujar una tabla vacía? En otras palabras, supongamos que la lista de elementos que se pasa, y es vacío – usted todavía desea dibujar la cabecera, a la derecha? La expresión lambda m => m[0] es asumir que lo que pasa en una lista (que es el motivo por el que el uso de IList no IEnumerable), y lo que es más importante es suponiendo que existe al menos un elemento en la lista! Que el código que se va a colapsar por una lista vacía, que parece un caso que necesita ser manejado.
    He encontrado la solución para los enlaces de código. En lugar de buscar el tipo de descuento en el primer elemento, puede utilizar IEnumerable y hacer lo siguiente: Tipo de itemType = lista.GetType().GetGenericArguments()[0]; ModelMetadata modelMetadata = ModelMetadataProviders.Actual.GetMetadataForType(null, itemType); puede foreach a través de modelMetadata.Propiedades.

    OriginalEl autor Clicktricity

  2. 0

    He encontrado una posible solución a esto, pero yo no estoy en amor con él; se requiere el uso de varios archivos basado en plantillas, lo que significa que no puede abstract este fácilmente en una biblioteca de código para su uso en múltiples proyectos.

    La Vista:

    <%
    StringBuilder sb = new StringBuilder();
    
    Type itemType = Model.GetType().GetGenericArguments()[0];
    
    sb.AppendLine("<table>");
    
    //Pass in the Model (IEnumerable<object>)'s generic item type as
    //the Model for a PartialView that draws the header
    sb.Append(Html.Partial("DisplayTableHead", itemType));
    
    foreach(object item in (IEnumerable<object>)Model)
    {
        sb.Append(Html.Partial("DisplayTableRow", item));
    }
    
    sb.AppendLine("</table>");
    %>
    <%= sb.ToString() %>

    Views/Shared/DisplayTableHead.ascx:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Type>" %>
    <tr>
    <%
    foreach (PropertyInfo prop in Model.GetProperties())
    {
    %>
    <th><%= prop.Name %></th>
    <%
    }
    %>
    </tr>

    Views/Shared/DisplayTableRow.ascx:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
    <tr>
    <%
    Type modelType = Model.GetType();
    
    foreach (PropertyInfo modelField in modelType.GetProperties())
    {
    %>
    <td><%= Html.Display(modelField.Name) %></td>
    <%
    }
    %>
    </tr>

    Pero ahora veo el mayor problema de esta solución, que es la que Clicktricity‘s publicado solución reconoce los detalles en el ModelMetadata – como si esa propiedad en particular se establece para mostrar, si es complejo o no, etc.

    Me pregunto un poco si MVC debe tener 4 tipos de plantilla – editar, mostrar, editRow, displayRow. De esa manera cuando usted pide el marco para dibujar un objeto como una fila de la tabla, se obtiene el derecho de la plantilla de ese tipo. Usted podría presumiblemente hack algo como esto en por tener que comprobar la existencia de un DisplayTableRow<Tipo>.ascx, y vuelven a caer en la generalización de la DisplayTableRow plantilla.

    OriginalEl autor Chris Moschini

Dejar respuesta

Please enter your comment!
Please enter your name here