带有嵌套模型类的Razor视图
本文关键字:Razor 视图 模型 嵌套 | 更新日期: 2023-09-27 17:52:35
我有一个嵌套类,如:
public class Jar
{
public IEnumerable<NailClippings> Nails { set; get; }
public IEnumerable<People> Donors { set; get; }
}
我的控制器将单个Jar
传递给我的视图,字符串类型为
@model Test.ViewModels.Jar
我可以很容易地遍历Nails
和Donors
的内容,就像这样
@foreach(var item in Model.Nails)
我的问题是使用HTML帮助生成显示名称为我
@Html.DisplayNameFor(model => model.Nails.Length)
我提出了一个解决方案,将内部嵌套类的类型更改为List
,在查询结束时附加.ToList()
,并将该行更改为
@Html.DisplayNameFor(model => model.Nails[0].Length)
被迫使用List
和索引[0]
来显示名称对我来说是愚蠢的。是否有其他方法来引用内部嵌套的类属性?
编辑:查看
<table>
<tr>
<th>@Html.DisplayNameFor(model => model.Nails[0].Length)</th>
.
.
</tr>
@foreach(var item in Model.Nails){
<tr>
<td>@Html.DisplayFor(modelItem => item.Length</td>
.
.
</tr>
}
</table>
您不需要在视图中编写任何循环。这让他们很丑。
只需为集合类型定义一个相应的显示模板。例如,您将创建~/Views/Shared/DisplayTemplates/NailClippings.cshtml
部分视图,它将强类型化为集合的单个元素:
@model NailClippings
<tr>
<td>
@Html.DisplayFor(x => x.Length)
</td>
.
.
</tr>
现在在你的主视图中,它就像这样简单:
@model Jar
<table>
<thead>
<tr>
<th>Length</th>
.
.
</tr>
</thead>
<tbody>
@Html.DisplayFor(x => x.Nails)
</tbody>
</table>
显示/编辑器模板按约定工作。在主视图中使用@Html.DisplayFor(x => x.Nails)
, ASP。. NET MVC将分析Nails
属性的类型,并将看到它是一个IEnumerable<NailClippings>
集合。因此,它将首先在~/Views/CurrentController/DisplayTemplates/NailClippings.cshtml
内开始寻找相应的显示模板,然后在~/Views/Shared/DisplayTemplates/NailClippings.cshtml
内,最后它将回落到default display template
。选择模板后,该模板将由ASP. js自动为您执行。为collection属性的每个元素使用。NET MVC,这样你就不必担心在视图中编写循环,担心索引等问题。
这也适用于编辑器模板:@Html.EditorFor(x => x.Nails)
将查找~/Views/Shared/EditorTemplates/NailClippings.cshtml
。您在这里得到的好处是,生成的输入字段将具有正确的名称,并且当您提交表单时,默认的模型绑定器将自动补充HttpPost操作作为请求参数的视图模型。
基本上,如果你尊重框架遵循的约定,你会让你的生活更容易。
代替
model.Nails[0].Length
你可以用
model.Nails.First().Length
无需转换为List
.
我认为你可以直接使用item
variable of loop
@Html.DisplayNameFor(model => item.Length)
UPDATE另一个选项是为钉子显示创建局部视图。它将被强类型设置为IEnumerable<NailClippings>
,并且所有属性都是可用的:
@Html.Partial("_Nails", Model.Nails)
钉子部分视图:
@model IEnumerable<NailClippings>
<table>
<tr>
<th>@Html.DisplayNameFor(model => model.Length)</th>
.
.
</tr>
@foreach(var item in Model){
<tr>
<td>@Html.DisplayFor(modelItem => item.Length)</td>
.
.
</tr>
}
</table>
我认为这个示例代码对嵌套模型类很有用
@model ViewModels.MyViewModels.Theme
@Html.LabelFor(Model.Theme.name)
@foreach (var category in Model.Theme)
{
@Html.LabelFor(category.name)
@foreach(var product in theme.Products)
{
@Html.LabelFor(product.name)
@foreach(var order in product.Orders)
{
@Html.TextBoxFor(order.Quantity)
@Html.TextAreaFor(order.Note)
@Html.EditorFor(order.DateRequestedDeliveryFor)
}
}
}