@ Html.DropDownListPara el uso básico

Estoy empezando a aprender MVC4 y debo admitir que me siento un poco desafiado por la confianza en las expresiones lambda, los generics y los tipos anónimos, especialmente cuando hay muchas funciones sobrecargadas. Es un poco confuso tratar de entender cómo funcionan los Ayudantes de HTML. Tome el ayudante “DropDownListFor”, por ejemplo. Intenté extraer lo esencial de mi código. Es por eso que solo ve una única columna, “Género”, en la tabla. Esperemos que todavía sea sintácticamente correcto:

@model IEnumerable  @foreach (var employee in Model) {  } 
@{ var listItems = new List() { new SelectListItem {Text = "Male", Value = "M"}, new SelectListItem {Text = "Female", Value = "F"} }; @Html.DropDownListFor(m => employee.Gender, listItems, listItems.Find(i => i.Value == employee.Gender).Text) }

Hay dos empleados en el objeto modelo, un IEnumerable de empleado y se genera el siguiente HTML

  Female Male Female  
Male Male Female

Mirando el primer parámetro del método DropDownListFor,

 @Html.DropDownListFor(m => employee.Gender, ... 

… ¿Entiendo correctamente que la “m” representa la instancia de la clase modelo que se pasó a la Vista? En los ejemplos en línea que he visto, he visto ejemplos en los que la “m” parece referirse a la clase modelo pero donde el modelo es una clase de instancia única, por ejemplo, un solo objeto Employee, en lugar de una colección de Employees como Es el caso aquí donde quiero mostrar una lista de la tabla de empleados. Supongo que la intención del primer parámetro del método DropDownListFor es “apuntar / enlazar” a una propiedad en el modelo, por eso hice m => employee.Gender. Es esto lo que debería hacer cuando el modelo ¿Es una colección de empleados en lugar de un solo empleado? Si es así, estoy confundido en cuanto a cómo puedo generar identificaciones únicas para las dos listas desplegables a las que se les asignó “employee_Gender” para los atributos NAME y ID.

Para el 3er parámetro del Helper DropDownListFor,

 listItems.Find(i => i.Value == employee.Gender).Text 

¿Es esto razonable? El valor para employee.Gender es “M” o “F”, pero el texto de la pantalla es “Masculino” y “Femenino”. Estoy confundido si este parámetro se usa para especificar un primer valor predeterminado “NO SELECCIONAR” o si este parámetro se usa para seleccionar desde el menú desplegable el valor del empleado actual, ¿o quizás puede hacer ambas cosas? Por ejemplo, ¿selecciona el texto especificado si se encuentra y agrega el texto especificado como PRIMERO? parámetro si el valor no se encuentra? Eso parece ser cómo funciona desde lo que veo. ¿Puede este tercer parámetro ser simplificado o mi ejemplo es razonable?

Gracias por su paciencia al leer mis muchas preguntas para tratar de entender mejor esto.

Parte 1: Explicando la magia Lambda

No estas solo. Lambdas + MVC hace que la encoding sea muy fácil, pero también hace que parezca bastante mágico (debido a la abstracción).

Viendo el primer parámetro del método DropDownListFor […] ¿Entiendo correctamente que la “m” representa la instancia de la clase modelo que se pasó a la Vista?

Sí.

HTML Helpers + Lambdas en Razor son simples y mágicos porque están tomando un atajo y no te revelan lo que está pasando.

Primero, echemos un vistazo a @Html . Sabemos que @ comienza nuestra syntax de Razor y luego Html es mágico. En realidad, Html es un objeto HtmlHelper que se inicializa automáticamente y se le entrega. Más específicamente es un HtmlHelper . El editor HTML de Razor es inteligente y sabe de antemano qué tipo de TModel se basará en el tipo de modelo de esta vista. Es por eso que tienes tanto intellisense.

Cuando escribes

 @model IEnumerable 

El editor lee eso y asume que el Ayudante de HTML será HtmlHelper> . Cuando llegue el momento de comstackr la página, el ayudante de HTML será ese tipo (por supuesto).

Entonces, ¿qué pasa con DropDownListFor o cualquier otro método de extensión?

Mirando a DropDownListFor podemos ver que en realidad es DropDownListFor . Ahora entendemos que TModel es el tipo de modelo de nuestra vista. DropDownListFor sabe porque el método está extendiendo HtmlHelper . Por lo tanto, DropDownListFor sabe que el tipo entrante es cualquier tipo definido en la parte superior de la vista. ¿Qué pasa con TProperty ?

TProperty es el tipo de retorno. Ese es el tipo que usted especifica cuando selecciona su propiedad. La vista le da a HtmlHelper el tipo de modelo, quien luego le da a DropDownListFor el tipo de modelo y ahora que está en una expresión lambda: (x => x.Property) selecciona la propiedad que luego selecciona el tipo para usted; en este caso una cadena (género).

Parte 2: tu problema

Es difícil responder a tu pregunta sin saber exactamente lo que estás tratando de lograr. ¿Tiene una colección de empleados y desea mostrar varios cuadros desplegables de género para cada uno y luego guardarlos?

Cuando se trata de colecciones, es un poco más complicado, ya que MVC no las maneja fuera de la caja; Por lo general, es mejor escribir sus propias soluciones de acuerdo con lo que necesita hacer.

Realmente no me gusta la idea de que una sola vista obtenga una colección de cosas en una página. Considera esta pieza de lógica:

A tu manera:

  • Obtener colección de empleados
  • Dar a los empleados una vista
  • Haga que la vista cree un solo SelectListItem
  • Recorra y muestre la Lista de selección para cada empleado

Mi manera

  • Obtener colección de empleados
  • Dar a los empleados una vista
  • Haga que la vista se desplace y pase cada empleado a otra vista (parcial)
  • Cada parte trata con un solo empleado

Con MVC intente dividir las cosas en partes pequeñas y lógicas. Las vistas deben ser estúpidas; lo que significa que realmente no deberían hacer ninguna lógica o pensamiento. Las cosas se vuelven más fáciles de esta manera y se asegura de que tus vistas no se conviertan en monstruos.

Ejemplo de solución a través de

Prueba esto:

Cree un nuevo PartialView llamado _ EmployeeGender.cshtml en la misma carpeta que la vista que está usando.

Usa este codigo

_EmployeeGender.cshtml

 @model BusinessLayer.Employee   @{ var listItems = new List() { new SelectListItem {Text = "Male", Value = "M"}, new SelectListItem {Text = "Female", Value = "F"} }; @Html.DropDownListFor(m => m.Gender, listItems, string.Empty) }   

Tu vista original

 @model IEnumerable @{ ViewBag.Title = "Employees"; } 

Employees

@foreach (var employee in Model) { Html.RenderPartial("_EmployeeGender", employee); }

Resultados

Echemos un vistazo a nuestro HTML generado ahora:

 

Podemos ver que ahora hay una selección en blanco y que nuestros cuadros desplegables se seleccionan automáticamente con los valores del Empleado (creo un empleado masculino y uno femenino).

Tenga en cuenta que los atributos de id y name HTML son los mismos. Si desea enviar un formulario con estos valores, necesitará más trabajo. Pero este es un punto de partida razonable para ti.