繁体   English   中英

MVC 3:HTML.DisplayFor和Lambda表达式

[英]MVC 3: HTML.DisplayFor and the Lambda expression

我找到了关于此的其他主题,但没有一个让我明白我想弄清楚的是什么。

我正在学习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.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做了什么? 是否还有其他情况,表达的第一部分变得重要?

如果可以将此表达式转换为适当的委托,那么这也可以帮助我理解究竟发生了什么。

非常感谢

我理解你的困惑。 实际上,lambda表达式中从不使用modelItem变量。 使用的是从外部上下文在闭包中捕获的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>

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

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

我认为很多html-helper扩展方法中的表达式实际上有点奇怪,但它是让代码获取所有这些信息的简单方法,而不必将其作为字符串参数写下来(如果你改变了什么,没有给出编译时错误)。

暂无
暂无

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

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