2012-07-27 45 views
5

我發現這方面的其他主題,但他們都不讓我明白我想弄清楚。MVC 3:HTML.DisplayFor和Lambda表達式

我學習MVC 3,我有我的包裹的頭周圍,在腳手架模板,@ HTML.DisplayFor()去Lambda表達式的問題。

我與MvcMusicStore示例應用程序的工作,由腳手架創建的視圖看起來像這樣:

@model IEnumerable<MvcMusicStore.Models.Album> 

... 

@foreach (var item in Model) { 
    <tr> 
     <td> 
      @Html.DisplayFor(modelItem => item.Genre.Name) 
     </td> 

我明白DisplayFor是一個擴展方法爲HTML和,它需要一個表達式作爲參數。我研究了Lambda表達式並在其他上下文中理解它們,例如使用可枚舉的字符串。例如:

cities.Where(s => s.StartsWith("L")); 

什麼博格爾斯我心中是,在第二個例子中,表達式(S)的第一部分實際上是在第二部分(s.startswith ..)使用,因此它是有道理的我得到了該程序正在做的事情。但是在MVC 3視圖中情況並非如此。 modelItem不在任何地方使用。我試圖重新命名只是「modelItem」到任何像這樣:

@Html.DisplayFor(iAmWearingShortPantsToday => item.Genre.Name) 

此代碼的作品一樣好,顯示所有的項目和值正常。這讓我懷疑在這種情況下,「modelItem」實際上用於任何事情。但是,那爲什麼呢?

我自己也嘗試把這種Lambda表達式爲代表(我相信這是對的縮寫形式),像這樣:

@(Html.DisplayFor(delegate(IEnumerable<MvcMusicStore.Models.Album> modelItem) { return item.Genre.Name; })) 

然而,這是行不通的。產生的錯誤是:

CS1946:匿名方法表達式不能轉換爲表達式樹

因此我的問題:

什麼是「modelItem」好? HTML.DisplayFor()用modelItem做什麼?也許還有其他一些情況,表達式的第一部分變得很重要?

如果有可能這種表達成適當的委託翻譯,這也可能會幫助我瞭解什麼確切回事。

非常感謝

+0

mint -good question +1 – 2012-07-27 13:48:13

回答

2

我明白你的困惑。實際上modelItem變量在lambda表達式中從不使用。使用的是item變量,它從外部上下文中捕獲到閉包中。所述item變量是簡單地在foreach環定義的局部變量。

通過當你看到像在ASP.NET MVC視圖modelItem => item.Genre.Name的表達方式,這通常是一個糟糕的編碼實踐的標誌。躲開它。互聯網充斥着這樣糟糕的例子。真。我很難看到這一點。請幫助我消除這種做法。

下面是一個替代方法,其中的變量是實際使用:

@model IList<MvcMusicStore.Models.Album> 
... 

@for (var i = 0; i < Model.Count; i++) { 
    <tr> 
     <td> 
      @Html.DisplayFor(x => x[i].Genre.Name) 
     </td> 
     ... 
    </tr> 
} 

甚至更​​好。爲什麼要寫循環呢?當我們可以直接使用編輯/顯示模板:

@model IEnumerable<MvcMusicStore.Models.Album> 
... 
@Html.DisplayForModel() 

,然後定義將自動ASP.NET MVC的模型集合(~/Views/Shared/DisplayTemplates/Album.cshtml

@model Album 
<tr> 
    <td> 
     @Html.DisplayFor(x => x.Genre.Name) 
    </td> 
    ... 
</tr> 
+0

您使用'for'而不是'foreach'循環的任何特定原因? – 2012-07-27 12:56:38

+0

是的,特別的原因是在StackOverflow中存在着數百萬個使用'foreach'和輸入字段的問題,比如'@ Html.TextBoxFor(modelItem => item.Name)'並詢問爲什麼POST操作沒有得到任何值返回。爲什麼模型始終爲空。你知道爲什麼嗎? – 2012-07-27 12:58:18

+0

1:你說modelItem => item.Genre.Name是不好的做法。但這正是默認MVC 3腳手架出來的。這怎麼可能是不好的做法?它也在我正在閱讀的書中,Wrox的Professional MVC 3。 2:所以如果沒有使用modelItem,爲什麼它在那裏?你有理論嗎? – 2012-07-27 14:38:46

0

的每個元素被呈現在顯示器模板不知道我可以回答你的問題,但正確的部分是用來告訴DisplayFor哪些屬性將創建一個顯示。它用於確定屬性的類型(用於選擇如何顯示值)和值。

如果用在TextBoxFor中,它也用於檢索屬性的名稱,所以文本框可以得到正確的名稱。

我認爲很多html-helper擴展方法中的表達式實際上有點奇怪,但它是讓代碼獲取所有這些信息的簡單方法,而不必將其寫成字符串參數(如果你改變了任何東西,那麼將會失敗,而沒有發生編譯時錯誤)。