Suppose you have a model like so:
假设你有这样一个模型:
class Foo
{
public int A {get; set;}
public int B {get; set;}
}
class SomeModel
{
public List<Foo> Foos { get; set; }
}
In a razor view on the ASP.NET mvc framework, you can do the following:
在一个刀片视图中ASP。NET mvc框架,你可以做以下事情:
@model SomeModel
@for(int i = 0; i < Model.Foos.Count; ++i)
{
Html.EditorFor(x => x.Foos[i]);
}
And the razor engine will happily spit out the correct html containing the index, and will call the editor template with the correct indexed instance.
razor引擎会很高兴地吐出包含索引的正确html,然后用正确的索引实例调用编辑器模板。
The EditorFor
method is a static extension method with the signature
编辑器方法是带有签名的静态扩展方法
public static MvcHtmlString EditorFor<TModel, TValue>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression
)
From the signature, it is clear that it is simply taking an expression, and the only context is coming from the HtmlHelper instance.
从签名中可以明显看出,它只是取一个表达式,惟一的上下文来自HtmlHelper实例。
I have done very limited Expression
tree processing, but from what I have seen, I can't see any way that this static method could know the information that it is somehow magically getting.
我已经做了非常有限的表达式树处理,但是从我所看到的,我看不出这个静态方法有什么方法可以知道它神奇地获得的信息。
How can the EditorFor
method figure out the index for generating html names and get the correct instance to pass to the editor template?
EditorFor方法如何确定生成html名称的索引并将正确的实例传递给编辑器模板?
1 个解决方案
#1
5
You are passing it an expression, not the value of x.Foos[i]
. MVC then evaluates that expression and figures out that you gave it a collection with an index. You would get the same result if you removed your entire loop and did:
传递给它的是表达式,而不是x.Foos[i]的值。然后MVC计算这个表达式,并计算出你给它一个带有索引的集合。如果你去掉整个循环,你会得到相同的结果:
Html.EditorFor(x => x.Foos)
MVC will then automatically render the editor template for all elements of the collection and generate proper names.
然后,MVC将自动呈现集合所有元素的编辑器模板并生成专有名称。
You can read more about how MVC handles display/editor templates here: Link
您可以在这里阅读更多关于MVC如何处理显示/编辑器模板的内容:链接
EDIT : To see this in action, here's a random piece of code I scribbled:
编辑:为了看到这一点,我随便写了一段代码:
List<string> list = new List<string>() { "A", "B", "C" };
var tester = new ExpressionTester<List<string>>(list);
var item = tester.Foo(p => p[0]);
You'll also need this class:
你也需要这门课:
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);
}
}
Stick a breakpoint in Foo() and look at the parameter expression
in debug. You'll find under Body -> Arguments the index you passed with the expression. Under Body -> Method you'll see that it is in fact a generic list.
在Foo()中插入断点,并查看debug中的参数表达式。您将在Body ->参数下找到与表达式一起传递的索引。在Body ->方法下,您将看到它实际上是一个泛型列表。
#1
5
You are passing it an expression, not the value of x.Foos[i]
. MVC then evaluates that expression and figures out that you gave it a collection with an index. You would get the same result if you removed your entire loop and did:
传递给它的是表达式,而不是x.Foos[i]的值。然后MVC计算这个表达式,并计算出你给它一个带有索引的集合。如果你去掉整个循环,你会得到相同的结果:
Html.EditorFor(x => x.Foos)
MVC will then automatically render the editor template for all elements of the collection and generate proper names.
然后,MVC将自动呈现集合所有元素的编辑器模板并生成专有名称。
You can read more about how MVC handles display/editor templates here: Link
您可以在这里阅读更多关于MVC如何处理显示/编辑器模板的内容:链接
EDIT : To see this in action, here's a random piece of code I scribbled:
编辑:为了看到这一点,我随便写了一段代码:
List<string> list = new List<string>() { "A", "B", "C" };
var tester = new ExpressionTester<List<string>>(list);
var item = tester.Foo(p => p[0]);
You'll also need this class:
你也需要这门课:
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);
}
}
Stick a breakpoint in Foo() and look at the parameter expression
in debug. You'll find under Body -> Arguments the index you passed with the expression. Under Body -> Method you'll see that it is in fact a generic list.
在Foo()中插入断点,并查看debug中的参数表达式。您将在Body ->参数下找到与表达式一起传递的索引。在Body ->方法下,您将看到它实际上是一个泛型列表。