Как смешивать HTML и код С# в MVC3 с Razor?
Я пытаюсь отобразить список элементов, которые должны переключать класс для целей стилизации. Идея заключается в создании цикла foreach, который будет циклически проходить через все myObj
в Модели.
Я пробовал следующий код, который не работает (потому что я делаю это неправильно)
@{ int i = 2;
foreach(var myObj in Model)
{
if (i % 2 == 0)
{
<div class="class1">
}
else
{
<div class="class2">
}
Html.Partial(...);
</div>
i += 1;
}
}
Каков правильный способ выполнить это?
Обновление
Я также попробовал следующий код, который, хотя и компилирует, не отображает HTML-код внутри (и я уверен, что есть объекты в модели).
@{ int i = 2;
foreach(var myObj in Model)
{
if (i % 2 == 0)
{
@:<div class="class1">
}
else
{
@:<div class="class2">
}
Html.Partial(...);
@:</div>
i += 1;
}
}
Это частичный класс, называемый
<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>
Извините, я не могу публиковать фактические имена и переменные.
Ответы
Ответ 1
Начните с улучшения кода.
-
Шаг 1:
@foreach(var myObj in Model.Select((model, index) => new { model, index }))
{
<div class="[email protected](myObj.index % 2 == 0 ? "1" : "2")">
@Html.Partial("_Foo", myObj.model)
</div>
}
-
Шаг 2 улучшения (используя специальный HTML-помощник для класса):
@foreach(var myObj in Model.Select((model, index) => new { model, index }))
{
<div class="@Html.MyClass(myObj.index)">
@Html.Partial("_Foo", myObj.model)
</div>
}
где MyClass определяется следующим образом:
public static string MyClass(this HtmlHelper html, int index)
{
return (index % 2 == 0) ? "class1" : "class2";
}
-
Шаг 3 усовершенствования, который является современным (с помощью Хранилища с ярлыками с шаблонами):
@Model.List(
@<div class="@item.MyClass">
@Html.Partial("_Foo", @item.Model)
</div>
)
где метод расширения List
выглядит следующим образом:
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);
}
});
}
}
Я прогоняю за улучшение номер 3, который намного лучше и более лаконичен, чем исходный цикл foreach.
Ответ 2
Вам нужно префикс строк с не-сформированными тегами @:
, чтобы предотвратить использование Razor для синтаксического анализа тегов.
Подробности.
Ответ 3
Вы можете быть уверены, что в какой-то модели есть объекты, но не ваша модель:)
следующий примерный код, полученный непосредственно из ваших, работает очень хорошо:
@{ 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;
}
}
Ответ 4
Вам нужно написать @Html.Partial(...)
, чтобы отобразить результат на странице.
Вызов Html.Partial
возвращает HelperResult
с частичным представлением, но фактически не отображает его.