2

我有一些类似于这些的视图模型:

public class ResturantViewModel
{
   public ResturantViewModel()
   {
       Clients.Add(new ClientViewModel());
   }
   public string MyProperty {get;set;}
   public IList<ClientViewModel> Clients = new List<ClientViewModel>();
}

public class ClientViewModel
{
   public string FirstName {get;set;}
   public string LastName {get;set;}
}

在我看来,我有类似的东西:

@foreach(var client in Model.Clients)
{
   <tr>
      <td>First Name: @Html.EditorFor(item => client.FirstName)</td>
      <td>Last  Name: @Html.EditorFor(item => client.LastName)</td>
   </tr>
}

我想要一个按钮,可以将一些新的空白 ClientViewModels 添加到 ResturantViewModel.Clients 列表,以便它可以在视图中呈现并发布到 Resturant/Create 操作。

提前致谢

4

3 回答 3

1

你可以看看下面的博客文章。它使用 WebForms 视图引擎,但可以很容易地适应 Razor。

于 2011-12-13T15:24:35.210 回答
1

您需要在视图中实现对象列表

  <input type="text" name='Clients[@index].FirstName' value='@c.FirstName' />
  <input type="text" name='Clients[@index].LastName'  value='@c.LastName' /> 

@index++;

之后,您必须使用下一个索引值克隆这些字段,因此您必须获得如下输入:

 <input type="text" name='Clients[0].FirstName' value='@c.FirstName' />
 <input type="text" name='Clients[0].LastName'  value='@c.LastName' /> 

 <input type="text" name='Clients[1].FirstName' value='@c.FirstName' />
 <input type="text" name='Clients[1].LastName'  value='@c.LastName' /> 
 <input type="text" name='Clients[2].FirstName' value='@c.FirstName' />
 <input type="text" name='Clients[2].LastName'  value='@c.LastName' /> 

在控制器中,您将接受这些对象的列表:

List<Client> Clients
于 2011-12-13T15:29:27.750 回答
0

好的,谢谢大家,这就是我要解决的问题。

首先我创建了一个新的局部视图_ClientRow.cshtml:

@using Extensions.CollectionItemsHtmlExtension
@using ClientViewModel
@model ClientViewModel
<div class = "clientEditRow">
   @using(Html.BeginCollectionItem("Clients"))
   {
      @First Name: @Html.TextBoxFor(c=>c.FirstName)
      @Last Name: @Html.TextBoxFor(c=>c.LastName)
   }
</div>

此局部视图为客户端呈现新行。BeginCollectionItem 是在 Darin 提到的博客文章之后下载的 Html 扩展。

然后在我看来,我设置:

<legend>Clients</legend>
<fieldset>
    <div id="clientEditorRows">
        @foreach(var client in Model.Clients)
        {
           Html.RenderPartial("_ClientRow", client);
        }
    </div>
    @Html.ActionLink("New Client", "NewClientRow", null, new {id = "addItem"})
</fieldset>
...
<script type="text/javascript" scr="../Scripts/listEditor.js"></script>

foreach 循环遍历所有客户端并为每个客户端呈现部分视图。然后在我的控制器中我写了这个方法:

public PartialViewResult NewClientRow()
{
   return PartialView("_ClientRow", new ClientViewModel())
}

此方法由 ActionLink 调用并返回新行的 html,并将其附加到前一行。最终,我从博客文章中添加了这个 javascript 文件代码并将其修改为我的案例:

listEditor.js

$("#addItem").click(function () {
    $.ajax({
        url: this.href,
        cache: false,
        success: function (html) { $("#clientEditorRows").append(html); }
    });
    return false;
});

此 js 代码将新行的 html 附加到页面。希望对大家有帮助,再次感谢大家。

亚历克斯

PS:接收值的 HttpPost 方法没有被修改并且有这个签名

[HttpPost]
public ActionResult Create(ResturantViewModel resturantVM)
{
   ...
}

请注意,resturantVM.Clients 接收所有值,无需添加 IList Clients 参数

于 2011-12-23T19:27:01.803 回答