如何在局部视图上批量持续?

时间:2012-01-20 11:55:58

标签: asp.net-mvc-3 razor

我编写了一个显示行列表的局部视图,其中行中的某些字段可以使用文本框,复选框或其他内容进行编辑。

我希望父视图有一个“提交”按钮,用于发布更新行的整个集合,这样我就可以进行组更新,而不是为每个更新的行发布一次。

这就是我所拥有的:

public class GroupModel {
  public string SomeGenericProperty { get; set; }
  public IEnumerable<ItemModel> Items { get; set; }
}

public class ItemModel {
  public long ID { get; set; }
  public string Field1 { get; set; }
  public string Field2 { get; set; }
}

然后我有一个视图“GroupDetails”:

@model MyNamespace.GroupModel
...
@using (Html.BeginForm("SaveItems", "Home")) {
  <fieldset>
  ...
  @Html.Partial("ItemList", Model.Items)
  ...
  <input type="submit" value="Approve" />
  </fieldset>
}

部分视图“ItemList”:

@model IEnumerable<MyNamespace.ItemModel>
<table>
  <tr>
    <th>
      &nbsp; Field 1 &nbsp;
    </th>
    <th>
      &nbsp; Field 2 &nbsp;
    </th>
    <th>
    </th>
  </tr>
  @foreach (var item in Model) {
    <tr>
      <td>
        &nbsp;
        @Html.TextBoxFor(modelItem => item.Field1)
        &nbsp;
      </td>
      <td>
        &nbsp;
        @Html.TextBoxFor(modelItem => item.Field2)
        &nbsp;
      </td>
      <td>
        @Html.HiddenFor(i => item.ID)
      </td>
    </tr>
  }
</table>

但是当我发布时,部分视图中的信息没有发布; GroupModel对象的Items属性为空。

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:4)

我建议你总是使用编辑器模板。您的代码无法工作的原因是因为您使用了部分代码而且此部分代码不会继承父模板上下文,这意味着在其中使用的帮助程序将为输入字段生成错误的名称。

例如,如果您查看页面的源代码,您会看到:

<td>
    &nbsp;
    <input type="text" name="[0].Field1" id="[0]_Field1" />
    &nbsp;
</td>

而不是正确的名称:

<td>
    &nbsp;
    <input type="text" name="Items[0].Field1" id="Items[0]_Field1" />
    &nbsp;
</td>

我建议您阅读following blog post以更好地了解默认型号装订器所期望的有线格式。

首先修复主视图,然后用编辑器模板替换partial:

@model MyNamespace.GroupModel
@using (Html.BeginForm("SaveItems", "Home")) 
{
    <fieldset>
        ...

        <table>
            <thead>
                <tr>
                    <th>&nbsp; Field 1 &nbsp;</th>
                    <th>&nbsp; Field 2 &nbsp;</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                @Html.EditorFor(x => x.Items)
            </tbody>
        </table>

        ...
        <input type="submit" value="Approve" />
    </fieldset>
}

然后定义将为模型的每个元素(~/Views/Shared/EditorTemplates/ItemModel.cshtml呈现的自定义编辑器模板 - 按惯例工作,如果您希望在其中重用它,它应该在~/Views/Shared/EditorTemplates内部控制器或内部~/Views/Home/EditorTemplates如果您希望此模板仅适用于Home控制器 - 并且模板的名称必须是集合的类型 - 在您的情况下是ItemModel.cshtml):

@model MyNamespace.ItemModel
<tr>
    <td>
        &nbsp;
        @Html.TextBoxFor(x => x.Field1)
        &nbsp;
    </td>
    <td>
        &nbsp;
        @Html.TextBoxFor(x => x.Field2)
        &nbsp;
    </td>
    <td>
        @Html.HiddenFor(x => x.ID)
    </td>
</tr>

现在一切都会在你的控制器动作中绑定得很好和花花公子:

[HttpPost]
public ActionResult SaveItems(GroupModel model)
{
    ...
}