MVC 3动态添加viewModel到View

发布于 2024-12-20 22:00:35 字数 807 浏览 0 评论 0原文

我有一些类似于以下的 viewModel:

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

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

提前致谢

I have some viewModels similar to these:

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;}
}

In my View I have something like:

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

I'd like to have a button which can add some new blank ClientViewModels to the ResturantViewModel.Clients list so that it could be rendered in the View and posted to the Resturant/Create action.

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柏林苍穹下 2024-12-27 22:00:35

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

You may take a look at the following blog post. It uses the WebForms view engine but it could be very easily adapted to Razor.

倾城花音 2024-12-27 22:00:35

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

  <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

You need to implement a list of objects inside your view

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

@index++;

after that you have to clone these fields with next index value, so you have to got inputs like these:

 <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' /> 

In controller you will accept a list of these objects:

List<Client> Clients
弄潮 2024-12-27 22:00:35

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

首先,我创建了一个新的部分视图 _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 附加到页面。
希望这可以帮助到大家,再次谢谢大家。

alex

P.S.:接收值的 HttpPost 方法尚未修改,并且具有此签名

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

以表明resturantVM.Clients 接收所有值,无需添加 IList Clients 参数

Ok thank to you all here is what I've done to resolve.

first I created a new partial View _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>

This partial view renders a new line for a client.
BeginCollectionItem is an Html Extension downloaded following the blog post Darin mentioned.

Then in my view I set:

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

the foreach loops through all the clients and renders the partial view for every client.
Then in my Controller I wrote this method:

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

This method is called by the ActionLink and returns the html for a new line appending it to the previous lines.
Eventually I added this javascript file code from the blog post and modified it to my case:

listEditor.js

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

This js code appends the html for the new line to the page.
Hope this can help, thank you all again.

alex

P.S.: the HttpPost method receiving the values hasn't been modified and has this signature

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

to note that resturantVM.Clients receives all the values, no need to add a IList Clients parameter

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文