MVC Razor @foreach

Nat*_*Pet 75 asp.net-mvc razor

我听说在视图中使用@foreach是禁忌.意思是,视图中不应该有任何逻辑.什么是@foreach逻辑应该在哪里的最佳实践?

    @foreach.. 
Run Code Online (Sandbox Code Playgroud)

Dar*_*rov 152

什么是@foreach逻辑应该在哪里的最佳实践?

无处,只是摆脱它.您可以使用编辑器或显示模板.

例如:

@foreach (var item in Model.Foos)
{
    <div>@item.Bar</div>
}
Run Code Online (Sandbox Code Playgroud)

完全可以被显示模板取代:

@Html.DisplayFor(x => x.Foos)
Run Code Online (Sandbox Code Playgroud)

然后您将定义相应的显示模板(如果您不喜欢默认模板).因此,您将定义一个可重用的模板~/Views/Shared/DisplayTemplates/Foo.cshtml,该模板将由框架为Foos集合的每个元素自动呈现(IEnumerable<Foo> Foos { get; set; }):

@model Foo
<div>@Model.Bar</div>
Run Code Online (Sandbox Code Playgroud)

显然,完全相同的约定适用于编辑器模板,如果您想要显示一些输入字段,允许您编辑视图模型,而不是仅显示为只读,则应使用这些模板.

  • @NicholasKing,这样的情况永远不应该出现.除了控制器操作传递的视图模型中的内容之外,视图不应该触及任何其他内容.如果它不在视图模型中,那么如果视图需要它,则应将其放在那里.这正是视图模型的意义所在. (5认同)
  • @DarinDimitrov如果你正在编写一个严格的MVC模型,那就是真的,但是如果出现需要循环的集合,而不是在模型中的情况,我没有看到使用foreach的问题 (3认同)
  • 那么,'foreach`的问题究竟是什么?至少一个显示模板(虽然一个完全可以接受的方法,无论如何)需要渲染一个新的视图,这是不自由的.大多数情况下,它不会显着影响您的网站加载时间,但如果做得足够,可能会导致性能下降.围绕一些HTML的"foreach"实际上是瞬间的.就像我说的那样,不管怎么说,这都不是什么大问题,但如果有的话,那就是*使用`foreach`的*. (3认同)
  • 如果集合中元素的类型不足以确定显示,该怎么办?例如,我的模型有一个字符串集合,但有时我想每行有一个字符串,在另一种情况下我想用逗号分隔它们? (2认同)

Jon*_*noW 90

当人们说不在视图中放置逻辑时,它们通常指的是业务逻辑,而不是渲染逻辑.在我的拙见中,我认为在视图中使用@foreach是完全没问题的.

  • 同意.让我想起旧的语义HTML争论,最终导致人们尝试使用div和CSS为实际的表格数据创建一个"表",因为它们是如此反表. (19认同)
  • 创建响应式视图不需要使用 div/css 创建表格数据视图吗? (2认同)

Mih*_*abo 12

我在@foreach发送包含实体列表的实体时使用(例如在1个视图中显示2个网格)

例如,如果我作为模型发送包含Foo1(List<Foo1>)和的实体FooFoo2(List<Foo2>)

我可以参考第一个List:

@foreach (var item in Model.Foo.Foo1)
{
    @Html.DisplayFor(modelItem=> item.fooName)
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*ing 9

对于我在剃须刀视图中使用foreach的情况回复@DarinDimitrov.

<li><label for="category">Category</label>
        <select id="category">
            <option value="0">All</option>
            @foreach(Category c in Model.Categories)
            {
                <option title="@c.Description" value="@c.CategoryID">@c.Name</option>
            }
        </select>
</li>
Run Code Online (Sandbox Code Playgroud)

  • @DarinDimitrov是的,我们在一个非常敏捷的环境中工作,这意味着像这样的场景有时会阻止我们使用像DropDownFor这样的东西,因为我们总是没有明确定义的要求.我相信在这种情况下,下拉最初并不需要"全部"然后它只是在视图中的一个DropDown中.由于此页面使用ajax更新其不是严格的MVC模式,并且您无法根据要求将产品上载到所有类别.不理想但有时不可避免. (7认同)
  • 哇,你会在视图中写出这样的东西吗?为什么不编写一个可重复使用的自定义帮助程序_Ltml.DropDownListFor`,它只会考虑标题?这是微不足道的,不会把你的意见变成意大利面条代码:http://stackoverflow.com/a/7938038/29407 (6认同)

小智 5

当使用重载来指示模板时,答案将不起作用@Html.DisplayFor(x => x.Foos, "YourTemplateName)

好像就是这么设计的,看这个案例。另外,框架给出的异常(关于类型不符合预期)非常具有误导性,并且在第一次尝试时愚弄了我(感谢@CodeCaster)

在这种情况下你必须使用@foreach

@foreach (var item in Model.Foos)
{
    @Html.DisplayFor(x => item, "FooTemplate")
}
Run Code Online (Sandbox Code Playgroud)