6

我有一个嵌套类,例如:

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

4 回答 4

9

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

只需为集合类型定义相应的显示模板。因此,例如,您将创建~/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.NET MVC 将自动为您执行该模板,用于集合属性的每个元素,这样您就不必担心在视图中编写一些循环、担心索引、...

这也适用于编辑器模板:@Html.EditorFor(x => x.Nails)将查找~/Views/Shared/EditorTemplates/NailClippings.cshtml. 您在这里获得的好处是生成的输入字段将具有正确的名称,并且当您提交表单时,默认模型绑定器将自动重新水化 HttpPost 操作作为请求参数的视图模型。

基本上,如果您尊重框架遵循的约定,您的生活就会变得更加轻松。

于 2013-01-11T21:50:04.777 回答
5

代替

model.Nails[0].Length

你可以使用

model.Nails.First().Length

无需转换为List.

于 2013-01-11T20:45:27.700 回答
2

我认为你可以只使用item循环变量

@Html.DisplayNameFor(model => item.Length)

为您更新另一个选项是为 Nails 显示创建部分视图。它将被强类型化,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>
于 2013-01-11T20:31:11.677 回答
0

我认为这个示例代码对嵌套模型类很有用

@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)
      }
   }
}
于 2013-01-11T21:38:10.317 回答