У меня есть IEnumerable базового типа в качестве моей модели.
Мне нужно отобразить другой бит HTML в списке в зависимости от конкретного типа.
Таким образом, получившийся список может выглядеть примерно так в HTML:
<ul>
<li class="points">Points - Item 1 - 10 points <a href="#">Remove</a></li>
<li class="media">Media - Item 2 - your_uploaded_image.jpg <a href="#">Remove</a></li>
<li class="content">Content - Item 3 <a href="#">Remove</a></li>
</ul>
Скорее всего, я добавлю еще один тип к этому позже, поэтому решения, подобные следующим, на самом деле не являются тем, что мне нужно.
@foreach(var item in Model)
{
if(item is PointImpl)
{
var pointItem = item as PointImpl;
<li class="points">Points - @pointItem.Name - @pointItem.Points points <a href="#">Remove</a></li>
}
else if(item is MediaImpl)
{
var mediaItem = item as MediaImpl;
<li class="media">Media - @mediaItem.Name - @mediaItem.FileName <a href="#">Remove</a></li>
}
/*
More implementations
*/
}
Я просмотрел подсказку шаблона метаданных модели, но это действительно не помогает, потому что моя модель IEnumerable..
Я думал о пользовательском Html Helper, который смотрел на атрибут конкретного типа, но думал, что может быть встроенный способ сделать это?
Вместо уродливого foreach
просто используйте шаблоны отображения:
@model IEnumerable<SomeBaseViewModel>
<ul>
@Html.DisplayForModel()
</ul>
а затем определить шаблоны отображения для всех дочерних типов. Например:
~/Views/Shared/DisplayTemplates/PointImpl.cshtml
:
@model PointImpl
<li class="points">
Points - @Model.Name - @Model.Points points
<a href="#">Remove</a>
</li>
и: ~/Views/Shared/DisplayTemplates/MediaImpl.cshtml
:
@model MediaImpl
<li class="media">
Media - @Model.Name - @Model.FileName
<a href="#">Remove</a>
</li>
Видишь, больше нет, нет больше циклов, нет больше варов. Все работает по соглашению (шаблоны должны располагаться в папке ~/Views/Shared/DisplayTemplates
или ~/Views/SomeController/DisplayTemplates
и должны называться именем конкретного типа - PointImpl.cshtml
, MediaImpl.cshtml
,...). На основе конкретного типа будет отображен соответствующий шаблон отображения, и это автоматически для каждого элемента основной коллекции модели.