[英]How does Html.EditorFor(…) know the index and item of a loop?
假設你有一個這樣的模型:
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名稱的索引並獲取傳遞給編輯器模板的正確實例?
你傳遞的是一個表達式,而不是x.Foos[i]
的值。 然后MVC評估該表達式,並確定您為其提供了一個帶索引的集合。 如果刪除整個循環並執行以下操作,則會得到相同的結果:
Html.EditorFor(x => x.Foos)
然后,MVC將自動為集合的所有元素呈現編輯器模板,並生成適當的名稱。
您可以在此處閱讀有關MVC如何處理顯示/編輯器模板的更多信息: 鏈接
編輯:要看到這一點,這里是我隨機編寫的一段代碼:
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中的參數expression
。 您將在Body - > Arguments下找到您使用表達式傳遞的索引。 在Body - > Method下你會看到它實際上是一個通用列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.