2012-06-11 24 views
5

Dada una claseseleccionar elementos de la lista <T> en MVC 4 utilizando modelo de unión

public class Person 
{ 
    // Some general properties 

    public List<Hobby> Hobbies { get; set; } 
} 

public class Hobby 
{ 
    // Some properties e.g. Name, etc. 
} 

static List<Hobby> AllHobbies { get; } 

¿Es posible crear una vista que permite al usuario seleccionar sus aficiones usando enlace de modelos?

Sin duda sería posible en la vista recorrer AllHobbies y renderizar <input type="checkbox" /> para cada uno, luego conectar los valores seleccionados manualmente en el controlador de devolución de datos. Parece que esto debería ser factible con el enlace del modelo, pero no veo cómo.

Respuesta

11

Seguro, le recomendaría que use plantillas de editor.

Supongamos que un hobby tiene un nombre y un campo booleano que indica si se ha seleccionado por el usuario:

public class Hobby 
{ 
    public string Name { get; set; } 
    public bool Selected { get; set; } 
} 

entonces un controlador para alimentar el modelo en la vista y procesar el envío del formulario:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var person = new Person 
     { 
      Hobbies = new[] 
      { 
       new Hobby { Name = "hobby 1" }, 
       new Hobby { Name = "hobby 2", Selected = true }, 
       new Hobby { Name = "hobby 3" }, 
      }.ToList() 
     }; 
     return View(person); 
    } 

    [HttpPost] 
    public ActionResult Index(Person person) 
    { 
     var selectedHobbies = person 
      .Hobbies 
      .Where(x => x.Selected).Select(x => x.Name); 
     string message = string.Join(",", selectedHobbies); 
     return Content("Thank you for selecting: " + message); 
    } 
} 

entonces una vista que contiene la forma que permite al usuario seleccionar aficiones:

@model Person 

@using (Html.BeginForm()) 
{ 
    <h2>Hobbies</h2> 
    @Html.EditorFor(x => x.Hobbies) 
    <button type="submit">OK</button> 
} 

y un editor de plantillas correspondiente, que será automáticamente procesa para cada elemento de la colección Hobbies (~/Views/Home/EditorTemplates/Hobby.cshtml -> aviso de que el nombre y la ubicación de la plantilla es importante):

@model Hobby 

<div> 
    @Html.LabelFor(x => x.Selected, Model.Name) 
    @Html.HiddenFor(x => x.Name) 
    @Html.CheckBoxFor(x => x.Selected) 
</div> 

Para los escenarios de edición más avanzadas que lo haría Te recomiendo que vayas a través de Steven Sanderson's blog post sobre este tema.

+0

+1, excelente información. Sin embargo, la clase 'Hobby' no tiene (y no debe) tener un booleano que indique si un usuario en particular lo ha seleccionado desde la perspectiva del modelo de dominio (este es un ejemplo simplificado del curso). ¿Tengo que agregar un campo booleano transitorio al objeto para soportar esto, o hay otra forma de hacer el enlace sin ese campo adicional? –

+4

No, su error es que está pasando un modelo de dominio a su vista. Esto está mal. Debe definir un modelo de vista. Dentro de este modelo de vista, tendrá una propiedad booleana 'Seleccionada' que le permitirá trabajar con las casillas de verificación dentro de la vista y obtener los valores seleccionados por el usuario. Luego, asignará el resultado a su modelo de dominio para hacer lo que tenga que hacer con él. Recuerde la regla más importante en MVC: las acciones del controlador pasan/toman solo vistas de modelos hacia/desde vistas. No modelos de dominio Los modelos de vista son clases que usted diseña específicamente para cumplir con los requisitos de la vista dada. –

+0

¿Puede recomendar un patrón para el mapeo eficiente (como en el tiempo pasado de codificación y prueba) entre el modelo de dominio y el modelo de vista? Esta es en realidad la primera instancia (aunque hago muy poco desarrollo de UI) donde ha habido alguna diferencia entre los dos. –

Cuestiones relacionadas