ASP.NET MVC 3: вывод конкретного представления для конкретной реализации

2

У меня есть 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, который смотрел на атрибут конкретного типа, но думал, что может быть встроенный способ сделать это?

Теги:
razor
asp.net-mvc-3

1 ответ

6
Лучший ответ

Вместо уродливого 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,...). На основе конкретного типа будет отображен соответствующий шаблон отображения, и это автоматически для каждого элемента основной коллекции модели.

  • 0
    Благодарю. Работает как шарм.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню