2012-01-05 82 views
3

好的,這是我第一次使用Lambda表達式,並且我一直在閱讀陰陽網站,只是想澄清我對我的理解是正確的- 可能不會!請溫柔:)ASP.NET MVC強類型HTML助手

讓我們走這條線:@Html.LabelFor(m => m.UserName) 這是一個頁面上這一行:@model CurrencyMvc.Models.RegisterModel

我認爲當頁面視圖渲染LabelFor與所描述的模型的引用自動調用,並且Lambda函數告訴它如何從模型中獲取所需的信息?

它不清楚爲什麼我們傳遞一個函數,當我們可以通過實際值例如m.Username。

哦,當這個幫手被稱爲「m」從哪裏來?

回答

3

我認爲當頁面視圖呈現LabelFor被稱爲 與所描述的模型的引用自動,那 lambda函數告訴它如何得到它從模型所需要的信息?

我不完全相信我明白你對這部分的含義,我想你的意思是@LabelFor如何知道使用哪種模型?

嗯,是的,如果你看一下syntax是這樣的:

public static MvcHtmlString LabelFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression 
) 

你可以看到第一個參數開始與this這使得它一種推廣方法。當你添加行@model CurrencyMvc.Models.RegisterModelthis HtmlHelper<TModel>成爲你的RegisterModel。

我不清楚爲什麼我們傳遞函數的時候我們可以通過 的實際值,例如, m.Username。

大部分時間是「λ表達式」是一個簡單的但Func<T>與您在Expression<Func<TModel, TValue>>這是一個lambda表達式樹數據結構通過剃刀@Html.xfor(如@Html.LabelFor)。通俗地說,一種未編譯的Func。

如果你通過m.Username該方法只會有「Dale Burrell」。但例如,HTML文本框作爲

<input type="text" name="Username" value="Dale Burrell"> 

所以產生的,你可以看到,它實際上需要m.Username變量名

哦,當這個助手叫哪裏「M」從何而來?

這只是一個變量。就像foreach(var m in dataset){}「m從哪裏來?」 - 你做到了。你可以用任何東西代替米

+0

好的,我認爲這對我來說是有意義的......它是一個漫長的一天,有很多新的信息。所以只是爲了澄清,爲簡單起見,我可以將LabelFor方法視爲在RegisterModel類中調用的方法(擴展)。然後在LabelFor方法中,它使用/調用'表達式'來獲取所需的值AND(大和這裏)也解構'表達式'以找出類中哪些屬性與值相關聯?從而考慮哪些屬性,驗證等等我是否在正確的軌道上? – 2012-01-05 09:35:12

+0

嗯..是的,除了「(擴展)在我的RegisterModel」; '這個HtmlHelper '是HtmlHelper的擴展,其中TModel是你的模型。在剃刀中,您可以像Html一樣使用HtmlHelper。所以,如果你不使用它作爲擴展,你可以使用'HtmlHelper(RegisterModel,m => m.UserName)'來代替。 - 但其餘的,這聽起來是對的。僅用於術語;它不解構表達式,它用Expression.Compile()方法編譯它。 – 2012-01-05 09:57:38

+0

是的,我想我正在接近我的頭,因爲它的HtmlHelp 它將從內部引用我的RegisterModel的一個實例?所以當我調用Html.LabelFor()時,它知道我的RegisterModel對象。 (當沒有RegisterModel存在時,它創建一個空白的?)對不起,如果我看起來很愚蠢,只是試圖在我的腦海中清楚。另外,當我說解構,我的意思是編譯Lambda表達式時,它也必須使用表達式樹來確定哪個對象屬性來查詢例如屬性。 [顯示名稱)]? – 2012-01-05 10:08:51

5

但是也有一些用於剃刀頁(從第一第二導出)2類:

  1. System.Web.Mvc.WebViewPage
  2. System.Web.Mvc.WebViewPage<T>

因此,當您通過指定使用強類型的視圖一個模型,您的視圖來自通用版本,Html屬性是一個通用的HtmlHelper<TModel>。因爲總是使用強類型視圖是一種好習慣,所以我不會再談論第一類,因爲它沒有興趣。

讓我們來看看LabelFor擴展方法的簽名:

public static MvcHtmlString LabelFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression 
) 
{ 
    ... 
} 

你可以從這個定義看LabelFor方法對於HtmlHelper<TModel>類需要1個參數的擴展方法。只有具有強類型視圖時,此方法纔可用。該參數表示一個僅限於成員訪問表達式的lambda表達式(如果您嘗試使用某些特殊的東西,該幫助器將拋出異常)。它將模型作爲參數,並且必須返回此模型的屬性。

由於這些信息,助手能夠確定正在指定的成員的名稱,從而生成正確的標記。由於參數是一個lambda表達式,因此它也可以確定此屬性的元數據(您可能已使用諸如[DisplayName]等屬性修飾了您的視圖模型屬性,允許您指定其他元數據)。如果助手只按照您詢問的那樣獲得了一個值:Html.LabelFor(Model.SomeValue)您知道在這個LabelFor方法中,您將獲得的是此值。您將永遠無法訪問視圖模型的元數據,這是ASP.NET MVC中的基本概念。

+0

謝謝你 - 我希望我可以給你信用,但其他答案是第一位的,我太新了,無法投票。您的帖子同樣有用。再次感謝。 – 2012-01-05 20:12:50