ASP.NET MVC 3: вывод конкретного представления для конкретной реализации - PullRequest
2 голосов
/ 27 июня 2011

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

1 Ответ

6 голосов
/ 27 июня 2011

Вместо уродливого 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>

Видите, больше нет ifs, больше нет циклов, больше нет переменных. Все работает по соглашению (шаблоны должны находиться в папке ~/Views/Shared/DisplayTemplates или ~/Views/SomeController/DisplayTemplates и должны называться в качестве имени конкретного типа - PointImpl.cshtml, MediaImpl.cshtml, ...). На основе конкретного типа будет отображаться соответствующий шаблон отображения, и это автоматически для каждого элемента основной коллекции моделей.

...