假设你有一个像这样的模型:
class Foo
{
public int A {get; set;}
public int B {get; set;}
}
class SomeModel
{
public List<Foo> Foos { get; set; }
}
在 ASP.NET mvc 框架的 Razor View 中,您可以执行以下操作:
@model SomeModel
@for(int i = 0; i < Model.Foos.Count; ++i)
{
Html.EditorFor(x => x.Foos[i]);
}
Razor 引擎会很高兴地吐出包含索引的正确 html,并使用正确的索引实例调用编辑器模板。
EditorFor
方法是具有签名的静态扩展方法
public static MvcHtmlString EditorFor<TModel, TValue>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression
)
从签名中可以清楚地看出,它只是采用一个表达式,唯一的上下文来自 HtmlHelper 实例。
我已经完成了非常有限的Expression
树处理,但是从我所看到的来看,我看不出这个静态方法有任何方式可以知道它以某种方式神奇地获得的信息。
EditorFor
方法如何找出用于生成 html 名称的索引并获取正确的实例以传递给编辑器模板?
最佳答案
您向其传递一个表达式,而不是 x.Foos[i]
的值。然后,MVC 评估该表达式并发现您为其提供了一个带有索引的集合。
如果删除整个循环并执行以下操作,您将得到相同的结果:
Html.EditorFor(x => x.Foos)
然后,MVC 将自动呈现集合中所有元素的编辑器模板并生成正确的名称。
您可以在此处阅读有关 MVC 如何处理显示/编辑器模板的更多信息:Link
编辑:要查看其实际效果,这是我随意编写的一段代码:
List<string> list = new List<string>() { "A", "B", "C" };
var tester = new ExpressionTester<List<string>>(list);
var item = tester.Foo(p => p[0]);
您还需要此类:
public class ExpressionTester<TModel>
{
private TModel _list;
public ExpressionTester(TModel list)
{
_list = list;
}
public TValue Foo<TValue>(Expression<Func<TModel, TValue>> expression)
{
var func = expression.Compile();
return func.Invoke(_list);
}
}
在Foo()中打断点,并在debug中查看参数表达式
。您将在“正文”->“参数”下找到您通过表达式传递的索引。在“主体”->“方法”下,您会看到它实际上是一个通用列表。
关于.net - Html.EditorFor(...) 如何知道循环的索引和项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14658139/