ASP.NET MVC 3: Output specific view for concrete implementation

一世执手 提交于 2019-12-06 11:07:45

问题


I have an IEnumerable of a base type as my model.

I need to display a different bit of HTML in a list depending on what the concrete type is.

So the resulting list might look similar to this in 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>

It's likely I will add another type to this later so solutions like the following aren't really what I'm after.

@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
   */
}

I've had a look at model metadata template hint but that doesn't really help because my model is an IEnumerable..

I was thinking about a custom Html Helper looking at an attribute on the concrete type but think there might be a built in way of doing this?


回答1:


Instead of the ugly foreach simply use display templates:

@model IEnumerable<SomeBaseViewModel>
<ul>
    @Html.DisplayForModel()
</ul>

and then define display templates for all child types. For example:

~/Views/Shared/DisplayTemplates/PointImpl.cshtml:

@model PointImpl
<li class="points">
    Points - @Model.Name - @Model.Points points 
    <a href="#">Remove</a>
</li>

and: ~/Views/Shared/DisplayTemplates/MediaImpl.cshtml:

@model MediaImpl
<li class="media">
    Media - @Model.Name - @Model.FileName 
    <a href="#">Remove</a>
</li>

See, no more ifs, no more loops, no more vars. Everything works by convention (templates must be situated in the ~/Views/Shared/DisplayTemplates or ~/Views/SomeController/DisplayTemplates folder and should be named as the name of the concrete type - PointImpl.cshtml, MediaImpl.cshtml, ...). Based on the concrete type the corresponding display template will be rendered and this automatically for each element of the main model collection.



来源:https://stackoverflow.com/questions/6495295/asp-net-mvc-3-output-specific-view-for-concrete-implementation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!