Dis*_*ile 42 asp.net-mvc display-templates asp.net-mvc-3
我在MVC中有以下模型:
public class ParentModel
{
public string Property1 { get; set; }
public string Property2 { get; set; }
public IEnumerable<ChildModel> Children { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我想显示父模型的所有子项时,我可以这样做:
@Html.DisplayFor(m => m.Children)
Run Code Online (Sandbox Code Playgroud)
然后我可以创建一个ChildModel.cshtml显示模板,DisplayFor将自动遍历列表.
如果我想为IEnumerable创建自定义模板怎么办?
@model IEnumerable<ChildModel>
<table>
<tr>
<th>Property 1</th>
<th>Property 2</th>
</tr>
...
</table>
Run Code Online (Sandbox Code Playgroud)
如何创建具有模型类型的显示模板,IEnumerable<ChildModel>
然后在@Html.DisplayFor(m => m.Children)
没有抱怨模型类型错误的情况下调用?
Dar*_*rov 62
像这样:
@Html.DisplayFor(m => m.Children, "YourTemplateName")
Run Code Online (Sandbox Code Playgroud)
或者像这样:
[UIHint("YourTemplateName")]
public IEnumerable<ChildModel> Children { get; set; }
Run Code Online (Sandbox Code Playgroud)
显然你会有~/Views/Shared/DisplayTemplates/YourTemplateName.cshtml
:
@model IEnumerable<ChildModel>
<table>
<tr>
<th>Property 1</th>
<th>Property 2</th>
</tr>
...
</table>
Run Code Online (Sandbox Code Playgroud)
小智 8
这是对马斯洛评论的回应.这是我对SO的第一次贡献,所以我没有足够的声誉来评论 - 因此回复作为答案.
您可以在ModelMetadataProvider中设置'TemplateHint'属性.这会自动将任何IEnumerable连接到您指定的模板.我只是在我的项目中尝试过.代码如下 -
protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
{
var metaData = base.CreateMetadataFromPrototype(prototype, modelAccessor);
var type = metaData.ModelType;
if (type.IsEnum)
{
metaData.TemplateHint = "Enum";
}
else if (type.IsAssignableFrom(typeof(IEnumerable<object>)))
{
metaData.TemplateHint = "Collection";
}
return metaData;
}
Run Code Online (Sandbox Code Playgroud)
您基本上覆盖'CachedDataAnnotationsModelMetadataProvider'的'CreateMetadataFromPrototype'方法,并将您的派生类型注册为首选的ModelMetadataProvider.
在模板中,您无法直接访问集合中元素的ModelMetadata.我使用以下代码访问我的集合中的元素的ModelMetadata -
@model IEnumerable<object>
@{
var modelType = Model.GetType().GenericTypeArguments[0];
var modelMetaData = ModelMetadataProviders.Current.GetMetadataForType(null, modelType.UnderlyingSystemType);
var propertiesToShow = modelMetaData.Properties.Where(p => p.ShowForDisplay);
var propertiesOfModel = modelType.GetProperties();
var tableData = propertiesOfModel.Zip(propertiesToShow, (columnName, columnValue) => new { columnName.Name, columnValue.PropertyName });
}
Run Code Online (Sandbox Code Playgroud)
在我看来,我只是调用@ Html.DisplayForModel()并加载模板.无需在模型上指定"UIHint".
我希望这有一些价值.
在我关于不从视图中获取输出的问题中,我实际上有一个如何使用子模型集合模拟模型并将它们全部渲染的示例.
实质上,您需要创建一个子类List<T>
或Collection<T>
使用它的模型:
@model ChildModelCollection
@foreach (var child in Model)
{
Html.DisplayFor(m => child);
}
Run Code Online (Sandbox Code Playgroud)
在您的模板中,集合模型用于迭代和渲染子项.每个孩子都需要强类型,因此您可能也想为项目创建自己的模型类型,并为这些项目设置模板.
所以对于OP问题:
public class ChildModelCollection : Collection<ChildModel> { }
Run Code Online (Sandbox Code Playgroud)
将制作一个强类型模型,该模型是一个可以像其他模板一样解析为模板的集合.
归档时间: |
|
查看次数: |
22712 次 |
最近记录: |