想象一下,我有一个实现名为ISummary的接口的对象列表 此列表中的对象可能具有其他属性,即
public interface ISummary {
Guid Id {get;set;}
string Title {get;set;}
DateTime Created {get;set;}
}
public class GigSummary: ISummary {
Guid Id {get;set;}
string Title {get;set;}
DateTime Created {get;set;}
string VenueName {get;set}
string Band {get;set;}
}
public class NewsSummary: ISummary {
Guid Id {get;set;}
string Title {get;set;}
DateTime Created {get;set;}
string Author{get;set}
}
我现在将这个Gigs和News Summary对象列表(作为一个ISummary列表)作为模型传递给视图。
我想使用列表中包含的每种类型的不同部分来呈现此列表。
我怎么能这样做是ASP.NET MVC?
答案 0 :(得分:8)
我能想到的最明显的方法是做一些事情:
foreach(ISummary summ in listOfISummary) {
Html.RenderPartial(String.Fomat("~/Views/Shared/{0}Renderer.ascx", summ.GetType.ToString()), summ, ViewData);%>
}
并创建一个带有命名约定的强类型视图,例如NewsSummaryRenderer.ascx。
我希望您可以将其移到辅助方法中,但是我会通过扩展方法将其添加到现有帮助程序中,而不是像之前建议的那样将其放在代码中。
答案 1 :(得分:0)
您可以在视图的代码隐藏中放置一个帮助方法,然后执行以下操作:
Type modelType = this.Model.GetType();
if (modelType == typeof(NewsSummary)) this.RenderPartial("newspartial", this.Model as NewsSummary);
else if (modelType == typeof(GigSummary)) this.RenderPartial("gigpartial", this.Model as GigSummary);
答案 2 :(得分:0)
查看Kona ASP.NET MVC示例应用程序以获取此概念的工作示例。
答案 3 :(得分:0)
我创建了一个HtmlHelper扩展来完成此任务。这里的一些伪代码看起来像c#一样令人震惊,可能确实有效:
public static void TemplatedList<T>(this HtmlHelper me, IEnumerable<T> items,
IDictionary<Type, Action<T>> templates)
{
foreach(var item in items)
{
var template = templates[item.GetType()];
if(template != null) template(item);
}
}
我会这样使用它:
<% HtmlHelper.TemplatedList(ViewData.Model, new Dictionary
{
{typeof(GigSummary), x => %>
<div class="gigSummary">
SUP! GIG ANNOUNCEMENT FOR <%= x.Band %>!!
What: <%= x.Title %>
When: <%= x.Created %>
Who: <%= x.Author %>
</div>
<%}
// add more type/template pairs here
}); %>
答案 4 :(得分:0)
这是一个简单的扩展方法,您可以创建它以仅提取所需的类型:
public static class Extensions
{
public static IEnumerable<U> ExtractOfType<U, T>(this IEnumerable<T> list)
where T : class
where U : class
{
foreach (var item in list)
{
if (typeof(U).IsAssignableFrom(item.GetType()))
{
yield return item as U;
}
}
}
}
测试:
public interface IBaseInterface
{
string Foo { get; }
}
public interface IChildInterface : IBaseInterface
{
string Foo2 { get; }
}
public interface IOtherChildIntreface : IBaseInterface
{
string OtherFoo { get; }
}
public class BaseImplementation : IBaseInterface
{
public string Foo { get { return "Foo"; } }
}
public class ChildImplementation : IChildInterface
{
public string Foo2 { get { return "Foo2"; } }
public string Foo { get { return "Foo"; } }
}
public class OtherChildImplementation : IOtherChildIntreface
{
public string OtherFoo { get { return "OtherFoo"; } }
public string Foo { get { return "Foo"; } }
}
...
List<IBaseInterface> b = new List<IBaseInterface>();
b.Add(new BaseImplementation());
b.Add(new ChildImplementation());
b.Add(new OtherChildImplementation());
b.Add(new OtherChildImplementation());
foreach (var s in b.ExtractOfType<IOtherChildIntreface, IBaseInterface>())
{
Console.WriteLine(s.GetType().Name);
}
这将获得列表中您正在寻找的派生类型的所有项目。因此,在您的控制器中,将整个列表传递给视图。然后,让部分视图采用部分需要的类型的IEnumerable,并在主视图中调用此扩展方法并将结果传递给那些单独的部分视图。