- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
假设我有一个简单的模型来解释用途:
public class Category
{
...
public IEnumerable<Product> Products { get; set; }
}
查看:
@model Category
...
<ul>
@Html.EditorFor(m => m.Products)
</ul>
编辑器模板:
@model Product
...
<li>
@Html.EditorFor(m => m.Name)
</li>
请注意,我不必为 IEnumerable<Product>
定义 EditorTemplate , 我只能为 Product
创建它模型和 MVC 框架足够聪明,可以使用自己的 IEnumerable 模板。它遍历我的集合并调用我的 EditorTemplate。
输出的 html 会是这样的
...
<li>
<input id="Products_i_Name" name="Products[i].Name" type="text" value="SomeName">
</li>
毕竟我可以将其发布到我的 Controller 。
但是,当我使用模板名称定义 EditorTemplate 时,为什么 MVC 不执行此操作?
@Html.EditorFor(m => m.Products, "ProductTemplate")
在这种情况下,我必须将属性的类型更改为 IList<Product>
,自己遍历集合调用EditorTemplate
@for (int i = 0; i < Model.Products.Count; i++)
{
@Html.EditorFor(m => m.Products[i], "ProductTemplate")
}
这对我来说似乎是一种肮脏的解决方法。是否有其他更清洁的解决方案来执行此操作?
最佳答案
好了,现在我只欠Darin 9999啤酒
public static MvcHtmlString EditorForMany<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable<TValue>>> expression, string templateName = null) where TModel : class
{
StringBuilder sb = new StringBuilder();
// Get the items from ViewData
var items = expression.Compile()(html.ViewData.Model);
var fieldName = ExpressionHelper.GetExpressionText(expression);
var htmlFieldPrefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
var fullHtmlFieldPrefix = String.IsNullOrEmpty(htmlFieldPrefix) ? fieldName : String.Format("{0}.{1}", htmlFieldPrefix, fieldName);
int index = 0;
foreach (TValue item in items)
{
// Much gratitude to Matt Hidinger for getting the singleItemExpression.
// Current html.DisplayFor() throws exception if the expression is anything that isn't a "MemberAccessExpression"
// So we have to trick it and place the item into a dummy wrapper and access the item through a Property
var dummy = new { Item = item };
// Get the actual item by accessing the "Item" property from our dummy class
var memberExpression = Expression.MakeMemberAccess(Expression.Constant(dummy), dummy.GetType().GetProperty("Item"));
// Create a lambda expression passing the MemberExpression to access the "Item" property and the expression params
var singleItemExpression = Expression.Lambda<Func<TModel, TValue>>(memberExpression,
expression.Parameters);
// Now when the form collection is submitted, the default model binder will be able to bind it exactly as it was.
var itemFieldName = String.Format("{0}[{1}]", fullHtmlFieldPrefix, index++);
string singleItemHtml = html.EditorFor(singleItemExpression, templateName, itemFieldName).ToString();
sb.AppendFormat(singleItemHtml);
}
return new MvcHtmlString(sb.ToString());
}
关于c# - EditorFor IEnumerable<T> 与 TemplateName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14038392/
我使用 Cordova 创建了一个示例应用程序以及一个与 Azure 通知中心通信的 Mvc5 应用程序。注册由后端处理,因为标签必须受到保护。 我们使用了从后端注册的三种不同的模板,分别适用于iOS
我有一个模板 chartEditPreview,一旦渲染的回调触发,它就会运行 D3.js 图表绘制函数。它看起来像这样: Template.chartEditPreview.rendered = f
假设我有一个简单的模型来解释用途: public class Category { ... public IEnumerable Products { get; set; } } 查看
我是 MeteorJS 新手。我正在阅读Discover Meteor在尝试构建我自己的应用程序时(而不是演示应用程序 Microscope )。在设置 router.js 时,我遇到了这个问题。当我
我希望使用这样的变量加载我的 View : {{#if model.isLoaded }} Loaded: {{ model.template.slug }} {{ view App.Docu
这是我的第一个 Meteor 项目,同时我正在尝试了解 Meteor 本身。现在我遇到了以下语法: Template.editor.rendered = function() { // som
我有一个看起来像这样的 View : @model Wellbore @(Html.Kendo().Grid() .Name("wellboresectiongrid")
我是一名优秀的程序员,十分优秀!