假设您有这样的模型:
class Foo
{
public int A {get; set;}
public int B {get; set;}
}
class SomeModel
{
public List<Foo> Foos { get; set; }
}
在ASP.NET mvc框架的剃刀视图中,您可以执行以下操作:
@model SomeModel
@for(int i = 0; i < Model.Foos.Count; ++i)
{
Html.EditorFor(x => x.Foos[i]);
}
剃刀引擎会愉快地吐出包含索引的正确html,并使用正确的索引实例调用编辑器模板。
EditorFor
方法是带有签名
public static MvcHtmlString EditorFor<TModel, TValue>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression
)
从签名中可以看出,它只是表达式,而唯一的上下文来自HtmlHelper实例。
我已经完成了非常有限的Expression
树处理,但是从我所看到的情况来看,我看不出这种静态方法可以知道它以某种方式神奇地获取的信息。
EditorFor
方法如何找出生成html名称的索引并获取传递给编辑器模板的正确实例?
答案 0 :(得分:6)
您传递的是表达式,而不是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()中粘贴断点并查看调试中的参数expression
。您将在Body下找到 - &gt;参数与表达式一起传递的索引。在Body下 - &gt;方法您将看到它实际上是一个通用列表。