简体   繁体   English

Html.EditorFor(...)如何知道循环的索引和项?

[英]How does Html.EditorFor(…) know the index and item of a loop?

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. 并且剃刀引擎将愉快地吐出包含索引的正确html,并将使用正确的索引实例调用编辑器模板。

The EditorFor method is a static extension method with the signature EditorFor方法是带有签名的静态扩展方法

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. 我已经完成了非常有限的Expression树处理,但是从我所看到的,我看不出这种静态方法可以知道它以某种方式神奇地获得的信息。

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名称的索引并获取传递给编辑器模板的正确实例?

You are passing it an expression, not the value of x.Foos[i] . 你传递的是一个表达式,而不是x.Foos[i]的值。 MVC then evaluates that expression and figures out that you gave it a collection with an index. 然后MVC评估该表达式,并确定您为其提供了一个带索引的集合。 You would get the same result if you removed your entire loop and did: 如果删除整个循环并执行以下操作,则会得到相同的结果:

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. 在Foo()中粘贴断点并查看debug中的参数expression You'll find under Body -> Arguments the index you passed with the expression. 您将在Body - > Arguments下找到您使用表达式传递的索引。 Under Body -> Method you'll see that it is in fact a generic list. 在Body - > Method下你会看到它实际上是一个通用列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM