mag*_*tte 8 mvc-editor-templates razor c#-4.0 asp.net-mvc-4
在MVC中,您可以为其创建编辑器模板T,然后当您想要为类型属性渲染编辑器时,IEnumerable<T>您可以简单地执行此操作
Html.EditorFor(m => m.MyListOfT)
Run Code Online (Sandbox Code Playgroud)
这样做的好处是,输入框架会自动创建名称,然后在回发模型绑定时,所有工作都很好.
我的问题是:当你有多种类型的编辑器模板时,你如何做到这一点?
我尝试过使用UIHint(),但它似乎只允许您针对列表指定UIHint,而不是列表中的每个项目.这意味着您必须使用foreach()循环为列表创建EditorTemplate,然后您错过了良好的自动命名和模型绑定.
我在这里错过了什么?
该模型是例如
public class MyViewModel
{
public IEnumerable<SomeType> SomeProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想做的事情如下:
public class MyViewModel
{
[UIHint("SomeTypeTemplate")]
public IEnumerable<SomeType> SomeProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并自动应用于列表中的所有元素,以便我可以使用以下内容进行渲染:
Html.EditorFor(m => m.SomeProperty)
Run Code Online (Sandbox Code Playgroud)
Dar*_*rov 10
我在这里错过了什么?
没有.不幸的是,它是如何的.如果在调用Html.EditorFor或使用UIHint时指定模板名称,则将为列表调用模板,而不是为每个元素调用模板.
这就是说你当然可以编写一个自定义扩展方法来实现这个功能:
public static class HtmlExtensions
{
private class ViewDataContainer: IViewDataContainer
{
public ViewDataContainer(ViewDataDictionary viewData)
{
ViewData = viewData;
}
public ViewDataDictionary ViewData { get; set; }
}
public static IHtmlString EditorForCollection<TModel, TProperty>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, IList<TProperty>>> expression
)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
if (string.IsNullOrEmpty(metadata.TemplateHint))
{
return html.EditorFor(expression);
}
var collection = metadata.Model as IList<TProperty>;
var sb = new StringBuilder();
for (int i = 0; i < collection.Count; i++)
{
var indexExpression = Expression.Constant(i, typeof(int));
var itemGetter = expression.Body.Type.GetProperty("Item", new[] { typeof(int) }).GetGetMethod();
var methodCallExpression = Expression.Call(expression.Body, itemGetter, indexExpression);
var itemExpression = Expression.Lambda<Func<TModel, TProperty>>(methodCallExpression, expression.Parameters[0]);
var result = html.EditorFor(itemExpression, metadata.TemplateHint).ToHtmlString();
sb.AppendLine(result);
}
return new HtmlString(sb.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
可以对使用UIHint属性修饰的类型集合的视图模型属性进行操作:
public class MyViewModel
{
[UIHint("SomeTypeTemplate")]
public IList<ItemViewModel> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在你看来:
@model MyViewModel
@Html.EditorForCollection(x => x.Items)
Run Code Online (Sandbox Code Playgroud)
~/Views/Shared/EditorTemplates/SomeTypeTemplate.cshtml现在你可以输入一个ItemViewModel:
@model ItemViewModel
...
Run Code Online (Sandbox Code Playgroud)
您不再需要中间显示模板,您只需循环并调用实际模板 - 这将是一个真正的浪费.
| 归档时间: |
|
| 查看次数: |
6631 次 |
| 最近记录: |