Ale*_*ner 5 c# asp.net-mvc asp.net-mvc-3
我找到了关于此的其他主题,但没有一个让我明白我想弄清楚的是什么.
我正在学习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>
Run Code Online (Sandbox Code Playgroud)
我知道DisplayFor是HTML的扩展方法,它将表达式作为参数.我研究了Lambda表达式并在其他上下文中理解它们,例如使用可枚举的字符串.例如:
cities.Where(s => s.StartsWith("L"));
Run Code Online (Sandbox Code Playgroud)
令我难以置信的是,在第二个例子中,表达式的第一部分实际上是在第二部分(s.startswith ..)中使用,所以它是有意义的,我得到程序用它做的事情.但在MVC 3视图中并非如此.modelItem不是在任何地方使用.我尝试将"modelItem"重命名为任何类似的东西:
@Html.DisplayFor(iAmWearingShortPantsToday => item.Genre.Name)
Run Code Online (Sandbox Code Playgroud)
此代码也可以正常工作,正确显示所有项目和值.这使我怀疑在这种情况下"modelItem"实际上用于任何事情.但那么,为什么呢?
我也尝试将这个Lambda表达式转换为委托(我认为它是简短形式),如下所示:
@(Html.DisplayFor(delegate(IEnumerable<MvcMusicStore.Models.Album> modelItem) { return item.Genre.Name; }))
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用.产生的错误是:
CS1946:无法将匿名方法表达式转换为表达式树
因此我的问题是:
什么是"modelItem"有用?HTML.DisplayFor()对modelItem做了什么?是否还有其他情况,表达的第一部分变得重要?
如果可以将此表达式转换为适当的委托,那么这也可以帮助我理解究竟发生了什么.
非常感谢
我理解你的困惑。实际上,modelItemlambda 表达式中从未使用变量。使用的是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>
}
Run Code Online (Sandbox Code Playgroud)
甚至更好。为什么要写循环呢?当我们可以直接使用编辑器/显示模板时:
@model IEnumerable<MvcMusicStore.Models.Album>
...
@Html.DisplayForModel()
Run Code Online (Sandbox Code Playgroud)
然后定义一个显示模板,该模板将由 ASP.NET MVC 自动为模型集合的每个元素呈现 ( ~/Views/Shared/DisplayTemplates/Album.cshtml)
@model Album
<tr>
<td>
@Html.DisplayFor(x => x.Genre.Name)
</td>
...
</tr>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7153 次 |
| 最近记录: |