2011-06-27 9 views
6

Estoy usando la maquinilla de afeitar MVC3. Tengo un escenario donde tengo que usar una vista parcial varias veces en la misma vista principal. El problema que tengo es que cuando se renderiza la vista principal, genera los mismos nombres y los identificadores de los controles de entrada dentro de esas vistas parciales. Como mis vistas parciales están vinculadas a diferentes modelos, cuando la vista se publica en "Guardar", se bloquea. ¿Alguna idea de cómo puedo hacer que los identificadores/nombres de control sean únicos, probablemente de alguna forma cómo prefijarlos?Uso de una vista parcial Múltiples veces en la misma Vista de padres

espera

Nabeel

Respuesta

5

Personalmente prefiero usar editor de plantillas, ya que cuidar de esto. Por ejemplo, podría tener la siguiente vista del modelo:

public class MyViewModel 
{ 
    public ChildViewModel Child1 { get; set; } 
    public ChildViewModel Child2 { get; set; } 
} 

public class ChildViewModel 
{ 
    public string Foo { get; set; } 
} 

y el siguiente controlador:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel 
     { 
      Child1 = new ChildViewModel(), 
      Child2 = new ChildViewModel(), 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

y dentro del Index.cshtml vista:

@model MyViewModel 
@using (Html.BeginForm()) 
{ 
    <h3>Child1</h3> 
    @Html.EditorFor(x => x.Child1) 

    <h3>Child2</h3> 
    @Html.EditorFor(x => x.Child2) 
    <input type="submit" value="OK" /> 
} 

y la última parte es el editor de plantillas (~/Views/Home/EditorTemplates/ChildViewModel.cshtml):

@model ChildViewModel 

@Html.LabelFor(x => x.Foo) 
@Html.EditorFor(x => x.Foo) 

Al utilizar EditorFor puede incluir la plantilla para las diferentes propiedades de su modelo de vista principal y se generarán nombres/ID correctos. Además de esto, obtendrá su modelo de vista debidamente poblado en la acción POST.

2

hay una alternativa:

  1. añadir un prefijo a la PartialView
  2. Enlazar el modelo, eliminando el prefijo

Para 1, establecer el prefijo en su Vista:

ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "prefix"; 

Para 2, puede recuperar los datos con UpdateModel, así:

UpdateModel(producto, "prefix"); 

Esto no es muy aconsejable porque su acción no recibe los datos como un parámetro, pero actualiza el modelo más tarde. Esto tiene varios inconvenientes: 1) no está claro qué necesita su acción al ver su firma 2) no es fácil proporcionar la entrada a la acción para probarla en unidades 3) la acción es vulnerable a los parámetros de desbordamiento (parámetros proporcionados por el usuario) eso no debería estar allí y están mapeados al modelo).

Sin embargo, para 2 existe una alternativa: registrar una Carpeta de modelo personalizada que le permita eliminar el prefijo. Y el Encuadernador de modelos personalizado debe saberlo.

Una buena solución es en este SO Q & A: How to handle MVC model binding prefix with same form repeated for each row of a collection? pero tiene un pequeño defecto: si agrega un campo oculto con el nombre "__prefix" en una vista parcial, y hacerla varias veces como una vista parcial , esta ID se repetirá para varios elementos diferentes en la página, lo cual no está permitido y puede provocar algunos problemas. Y una de las razones más importantes para proporcionar un prefijo es precisamente la representación de la misma vista de "edición" como vistas parciales para varias instancias de una entidad. Es decir.esto sucedería en una página como gmail, donde puedes editar varios correos electrónicos a la vez.

Existen varias soluciones posibles para este problema.

Uno de ellos proporciona el prefijo como una cadena de consulta o un valor de datos de ruta, y no como un campo de formulario, lo que evita los conflictos de Id. Y puede ser encontrado por el archivador del modelo. (Siempre puede tener el mismo nombre).

Otra solución es utilizar un campo oculto, con un patrón fijo, pero que es diferente para cada vista procesada. El prefijo podría seguir este patrón por singularidad: "PP $ ActionControllerId" como "PP $ EditProduct23", que es único para cada vista procesada, y se puede encontrar fácilmente entre los parámetros de solicitud buscando uno que comience por "PP $".

Y una solución final sería crear el prefijo solo en la vista y no proporcionarlo en ningún tipo de parámetro de solicitud. La carpeta de Modelos debería buscar el prefijo que examina los nombres de los parámetros de solicitud, hasta que encuentre uno cuyo prefijo siga el patrón.

Por supuesto, el ModelBinder personalizado debe adaptarse para funcionar según la convención elegida.

Cuestiones relacionadas