Asp.net mvc MVC剃须刀@foreach
我听说在视图中包含@foreach是不允许的。也就是说,视图中不应该包含任何逻辑。关于@foreach的逻辑应该在哪里,最佳实践是什么Asp.net mvc MVC剃须刀@foreach,asp.net-mvc,razor,Asp.net Mvc,Razor,我听说在视图中包含@foreach是不允许的。也就是说,视图中不应该包含任何逻辑。关于@foreach的逻辑应该在哪里,最佳实践是什么 @foreach.. 关于@foreach的逻辑应该在哪里,最佳实践是什么 没有,就把它扔掉吧。您可以使用编辑器或显示模板 例如: @foreach (var item in Model.Foos) { <div>@item.Bar</div> } 然后您将定义相应的显示模板(如果您不喜欢该模板)。因此,您将定义一个
@foreach..
关于@foreach的逻辑应该在哪里,最佳实践是什么
没有,就把它扔掉吧。您可以使用编辑器或显示模板
例如:
@foreach (var item in Model.Foos)
{
<div>@item.Bar</div>
}
然后您将定义相应的显示模板(如果您不喜欢该模板)。因此,您将定义一个可重用模板~/Views/Shared/DisplayTemplates/Foo.cshtml
,该模板将由框架为Foos集合的每个元素自动呈现(IEnumerable Foos{get;set;}
):
@model Foo
@模型酒吧
显然,同样的约定适用于编辑器模板,如果您希望显示一些输入字段,允许您编辑视图模型,而不是仅将其显示为只读,则应使用这些模板。当我发送包含实体列表的实体时,我使用的是
@foreach
(例如,在一个视图中显示两个轴网)
例如,如果我作为模型发送包含Foo1(列表)
和Foo2(列表)
我可以参考第一个列表:
@foreach (var item in Model.Foo.Foo1)
{
@Html.DisplayFor(modelItem=> item.fooName)
}
当人们说不要在视图中放置逻辑时,他们通常指的是业务逻辑,而不是呈现逻辑。在我看来,我认为在视图中使用@foreach是非常好的。关于我在razor视图中使用foreach的案例的回复
<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>
类别
全部的
@foreach(模型类别中的c类)
{
@c、 名字
}
当使用重载指示模板@Html.DisplayFor(x=>x.Foos,“YourTemplateName”)时,
将不起作用
似乎是这样设计的,。而且框架给出的例外(关于类型不是预期的)是相当误导的,并且在第一次尝试时愚弄了我(谢谢@CodeCaster)
在这种情况下,您必须使用@foreach
@foreach (var item in Model.Foos)
{
@Html.DisplayFor(x => item, "FooTemplate")
}
你从哪里读到的?逻辑是razor的本意!请阅读下面的ms教程@DarinDimitrov,如果它是一个严格的MVC模型,那么这是正确的。但是,如果出现需要循环收集的情况,而该集合不在模型中,我认为使用它没有问题foreach@NicholasKing,这样的情况应该永远不会出现。视图不应该接触控制器操作传递的视图模型中存在的内容以外的任何内容。如果它不在视图模型中,那么如果视图需要,您应该将它放在视图模型中。这正是视图模型的用途。@MihaiLabo,是的,我就是这么说的。如果集合中元素的类型还不足以确定显示?例如,我的模型有一个字符串集合,但有时我希望每行有一个字符串,而在另一种情况下,我希望它们用逗号分隔?那么,foreach
的问题到底是什么呢?至少是一个显示模板(无论如何,这是一种完全可以接受的方法)需要呈现一个新的视图,这不是免费的。大多数情况下,它不会显著影响站点加载时间,但如果做得足够,它可能会导致性能下降。一点HTML周围的foreach
几乎都是即时的。正如我所说的,这两种方式都不是什么大问题,但是如果有什么问题的话使用foreach
的一个论点。哇,伙计,你会在视图中写这样的东西吗?为什么不编写一个可重用的自定义帮助程序呢?Html.DropDownListFor
,它只会考虑标题?它很简单,不会把你的视图变成意大利面代码:@DarinDimitrov是的,我们在一个非常敏捷的环境中工作,这是这意味着像这样的场景有时会阻止我们使用像DropDownFor这样的东西,因为我们并不总是有明确定义的需求。我相信在这种情况下,DropDownFor最初并不需要“全部”"然后它就这样做了,但只是在视图上的一个下拉列表中。由于此页面使用ajax更新其不是严格的MVC模式,并且您无法根据需求将产品上传到所有类别中。这并不理想,但有时不可避免。也许更好的示例是使用此选项在选择列表中呈现optgroup
元素,因为没有支持如果你只需要在选择列表中添加一个额外的项目,有更好的方法来实现这一点,然后仍然使用帮助器。这不是我对敏捷的定义——我必须同意@darindimitrovaled。这让我想起了过去关于语义HTML的争论,最终导致人们尝试使用divs和CSS to创建一个“表”对于实际的表格数据,因为它们是如此的反表格。我同意。人类不擅长错误的方向。我真的需要一个新的文件夹,一个新的视图,只是为了在我的viewmodel中显示列表中的内容吗?使用div/css来创建表格数据视图不是创建响应视图所必需的吗?这个答案是由一个在MVC上工作的人写的,所以我我猜他们知道他们在说什么。MVC将迭代IEnumerable
,并为每个元素调用类型T
的模板。关于编辑:要么是您的代码出错,要么是特定MVC版本中的错误(在5.2.2中,它对我有效)。它应该按照公认的答案中的描述工作。与其说它是错误的,不如根据你的意愿就这个问题提出你自己的问题。@CodeCaster我相信我的回答为这个具体案例提供了一些线索(它浪费了我的一些时间来找出哪里出了问题)。请你为保留否决票添加一些解释好吗?(谢谢你的时间,顺便说一句,我只是想弄清事情的真相)我认为这不是一个好答案,因为它没有验证错误,这有助于世界上的谣言,比如“一个显示模板不能迭代”-它应该是这样的,所以它应该可以工作。如果它是真的
<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>
@foreach (var item in Model.Foos)
{
@Html.DisplayFor(x => item, "FooTemplate")
}