asp.net mvc 3 - update - ¿Cómo mezclar código HTML y C#en MVC3 con Razor?
viewmodel asp net mvc 4 (4)
Estoy tratando de mostrar una lista de elementos que deben alternar una clase para fines de diseño. La idea es crear un ciclo foreach que myObj
todos los myObj
en el Modelo.
Probé el siguiente código que no funciona (porque lo estoy haciendo mal)
@{ int i = 2;
foreach(var myObj in Model)
{
if (i % 2 == 0)
{
<div class="class1">
}
else
{
<div class="class2">
}
Html.Partial(...);
</div>
i += 1;
}
}
¿Cuál es la forma correcta de lograr esto?
Actualizar
También probé el siguiente código que, aunque compila, no representa ningún código HTML (y estoy seguro de que hay objetos en el Modelo).
@{ int i = 2;
foreach(var myObj in Model)
{
if (i % 2 == 0)
{
@:<div class="class1">
}
else
{
@:<div class="class2">
}
Html.Partial(...);
@:</div>
i += 1;
}
}
Esta es la clase parcial que se llama
<div class="class">
<div class="class2">
@if (string.IsNullOrEmpty(var))
{
@var2
}
else
{
@var
}
</div>
<div class="class3">
@var3
</div>
</div>
<div class="class4">
<p>var4</p>
<ul class="class5">
<li>element1</li>
<li>element2</li>
</ul>
</div>
Lo siento, no puedo publicar los nombres y las variables reales.
Comencemos por mejorar tu código.
Mejora paso 1:
@foreach(var myObj in Model.Select((model, index) => new { model, index })) { <div class="class@(myObj.index % 2 == 0 ? "1" : "2")"> @Html.Partial("_Foo", myObj.model) </div> }
Mejora Paso 2 (usando un ayudante de HTML personalizado para la clase):
@foreach(var myObj in Model.Select((model, index) => new { model, index })) { <div class="@Html.MyClass(myObj.index)"> @Html.Partial("_Foo", myObj.model) </div> }
donde MyClass se define así:
public static string MyClass(this HtmlHelper html, int index) { return (index % 2 == 0) ? "class1" : "class2"; }
Mejora del paso 3, que es el estado de la técnica (usando delegados de navaja con plantilla ):
@Model.List( @<div class="@item.MyClass"> @Html.Partial("_Foo", @item.Model) </div> )
donde el método de extensión de
List
se ve así:public class ModelHolder<T> { public T Model { get; set; } public string MyClass { get; set; } } public static class RazorExtensions { public static HelperResult List<T>( this IEnumerable<T> items, Func<ModelHolder<T>, HelperResult> template ) { return new HelperResult(writer => { foreach (var item in items.Select((model, index) => new { model, index })) { var myClass = item.index % 2 == 0 ? "class1" : "class2"; template(new ModelHolder<T> { Model = item.model, MyClass = myClass }).WriteTo(writer); } }); } }
Voto la mejora número 3, que es mucho mejor y más concisa que el ciclo foreach original.
Es necesario que prefijas las líneas con etiquetas no formadas con @:
para evitar que Razor intente analizar las etiquetas.
Details .
Necesita escribir @Html.Partial(...)
para @Html.Partial(...)
el resultado a la página.
Llamar a Html.Partial
devuelve un HelperResult
con la vista parcial, pero en realidad no lo representa.
Puede estar seguro de que hay objetos en algún modelo, pero no su modelo:) el siguiente código de ejemplo derivado directamente del suyo funciona bien:
@{ int i = 2;
string[] list = new string[] {"a","b","c","d"};
foreach(var myObj in list)
{
if (i % 2 == 0){
@:<div class="class1">
}
else
{
@:<div class="class2">
}
//Html.Partial(...);
@:</div>
i += 1;
}
}