2012-06-26 25 views
7

vamos a considerar dos vistas que utilizan el mismo diseño compuesto por:Asp.Net MVC de diseño y vistas parciales en

  • Una columna de la izquierda que contiene un "cuerpo" (que se llena de manera diferente por ambas visitas)
  • A columna derecha que muestra información general (aprobada a través del modelo)

En lugar de definir la parte correcta dos veces, me pregunté si podría crear una Vista parcial para vincular directamente desde la página de diseño.

El problema es que las vistas parciales heredan implícitamente sus modelos de la vista que se está representando. Y como cada vista tiene su propio modelo, termino con una discrepancia en el tipo de modelo en la vista parcial.

Desde aquí veo dos soluciones:

  • pude insertar la parte común del modelo de vista en el ViewBag. Desafortunadamente, esto significa que cada vista que utiliza este diseño tiene que implementar esta "convención" pero nada advierte al desarrollador al respecto en tiempo de compilación ...
  • Podría usar el polimorfismo para hacer que cada modelo de vista herede de la misma clase base (editar : o interfaz) que usa Vistas parciales. Esto funcionaría hasta cierto punto, pero potencialmente aumentaría exponencialmente en complejidad tan pronto como tenga una segunda vista parcial en el mismo diseño.

Así que aquí están las preguntas:

  • Estoy en lo cierto con los supuestos anteriores?
  • ¿Ve alguna otra posibilidad?
  • ¿Alguna experiencia de retorno en esto?

Muchas gracias, TB.

+0

Hacia el 2017, también podría hacer que la porción común sea propiedad de cada modelo, y luego pasarla como el modelo a '@ Html.RenderPartial' – jpaugh

Respuesta

7

Utilice un Interface y ejecútelo en los dos modelos, este es exactamente el tipo de cosa para la que se utilizan.

Aquí hay un ejemplo de dos vistas diferentes que utilizan dos modelos diferentes que implementan una interfaz. Esto es subtyping en lugar de ad-hoc polymorphism.

public class ViewModelOne : IReusableView 
{ 
    public string Name { get; set; } 
    public string Something { get; set; } 
    public int ANumber { get; set; } 
} 

public class ViewModelTwo : IReusableView 
{ 
    public string Name { get; set; } 
    public string Thing { get; set; } 
    public string SomethingElse { get; set; } 
    public int ANumber2 { get; set; } 
} 

public interface IReusableView 
{ 
    string Name { get; } 
} 

Así que tenemos la vista parcial muy simple aquí que es 'InnerPartialView':

@model TestIntegration.Models.IReusableView 
<div> 
    @Model.Name 
</div> 

que se utiliza en el hogar y sobre las páginas de este ejemplo de controlador:

public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      ViewBag.Message = "Welcome to ASP.NET MVC!"; 

      return View(new ViewModelOne() { Name = "hello", Something="sdfsdfs", ANumber = 1 }); 
     } 

     public ActionResult About() 
     { 
      return View(new ViewModelTwo() { Name = "hello 2", SomethingElse = "aaaddd", ANumber2 = 10, Thing="rand" }); 
     } 
    } 

La vista de inicio:

@model TestIntegration.Models.ViewModelOne 
@{ 
    ViewBag.Title = "Home Page"; 
} 

<h2>@ViewBag.Message</h2> 
<p> 
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>. 
    @Html.Partial("InnerPartialView") 
</p> 

La acerca vista:

@model TestIntegration.Models.ViewModelTwo 
@{ 
    ViewBag.Title = "About Us"; 
} 

<h2>About</h2> 
<p> 
    Put content here. 
     @Html.Partial("InnerPartialView") 
</p> 
+0

Esto es lo que quise decir con" baseclass ". Solo me temo que una vez que obtenga múltiples vistas parciales, mis modelos de vista crecerán bastante rápido en complejidad, implementando esta o aquella interfaz dependiendo del contexto. Supongo que es mejor que la alternativa que mencioné, pero me sorprende no encontrar las mejores prácticas aquí ... –

+0

Una clase base e interfaz son muy diferentes. He actualizado con un ejemplo completo ya que no hay nada complejo sobre esto. No se exceda con esto, si está agregando un menú, por ejemplo, no lo colocará en ViewModel, lo pasará en el controlador usando viewbag y lo manejará en la página de diseño. Este método se debe usar para la funcionalidad que desea reutilizar en objetos, no para elementos como pies de página, menús o barras laterales. – mattmanser

+0

Como dijo que el panel derecho mostraba información "general", esto implica que muestra información bastante genérica, por lo que no dependería demasiado de la subclase detallada. No ha dicho mucho sobre el dominio de su aplicación, por lo que es difícil de decir. Por ejemplo, si es un sitio para recetas de comida, esperaría que cada receta (sin importar qué subclase) tenga unas pocas propiedades comunes (título, rendimiento, tiempo de cocción) y estas podrían expresarse en una interfaz. Si su sitio maneja tipos muy diversos sin nada en común, entonces puede que no haya ninguna información "general" significativa para mostrar –

3

Al representar la vista parcial, se puede enviar un modelo:

@Html.RenderPartial(MVC.Partials.Views.Sidebar, Model.SideBarModel); 

por lo que podría hacer bajar los datos como parte del modelo de matriz que es el modelo de la barra lateral parcial.

+0

. Eso funcionaría si supiera cuál era el modelo. Dado que estoy realizando este RenderPartial en el diseño, mi modelo puede ser cualquier cosa. A menos que tenga una base de datos o una interfaz común para todos mis modelos, no puedo asumir nada sobre ellos. –

0

En vistas parciales, los modelos son de tipo dynamic por lo que no necesita saber de qué tipo son. Sin embargo, solo necesita asegurarse de que el modelo tenga la propiedad que necesita. En otras palabras, puede usar Model.MyProperty o Model.MyProperty como MyPropertyType cuando usa Html.Partial.

Cuestiones relacionadas