带有嵌套模型类的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

我可以很容易地遍历NailsDonors的内容,就像这样

@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>

带有嵌套模型类的Razor视图

您不需要在视图中编写任何循环。这让他们很丑。

只需为集合类型定义一个相应的显示模板。例如,您将创建~/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)
      }
   }
}