5

我找到了有关此的其他主题,但没有一个让我了解我想要弄清楚的内容。

我正在研究 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 有什么作用?是否还有其他情况,表达式的第一部分变得重要?

如果可以将此表达式转换为适当的委托,那也可能有助于我理解到底发生了什么。

非常感谢

4

2 回答 2

2

我理解你的困惑。实际上modelItem变量从未在 lambda 表达式中使用。使用的是item从外部上下文在闭包中捕获的变量。item变量只是foreach循环中定义的局部变量。

顺便说一句,当您modelItem => item.Genre.Name在 ASP.NET MVC 视图中看到类似的表达式时,这通常表明编码习惯不好。躲开它。互联网上充斥着这样的坏例子。真的。我讨厌看到这个。请帮助我根除这种做法。

这是实际使用变量的另一种方法:

@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>
于 2012-07-27T12:51:34.313 回答
0

不确定我能否回答您的问题,但正确的部分用于说明DisplayFor将为哪个属性创建显示。它用于确定属性的类型(用于选择如何显示值)和值。

如果在 TextBoxFor 中使用,它还用于检索属性的名称,因此文本框可以获得正确的名称。

我认为很多 html-helper 扩展方法中的表达式实际上有点奇怪,但这是让代码获取所有这些信息的简单方法,而无需将其写为字符串参数(如果您更改了任何内容,但没有给出编译时错误)。

于 2012-07-27T12:51:43.670 回答