8

我想使用 java 脚本动态地将项目添加到我的模型中的列表中。如何让 MVC 将新项目绑定到模型?

我的模型:

public class Garage
{
    public string Name{ get; set; }
    public string Location { get; set; }
    public IList<Car> Cars{ get; set; }
}

public class Car
{
    public string Color{ get; set; }
    public string Name { get; set; }
}

我的观点,它使用车库作为模型:

<% using (Html.BeginForm())
{%>
<div id="cars">
         <% 
               foreach (var item in Model.Cars)
               {
                  Html.RenderPartial("CarView", item);
              } %>
</div>
<% } %>

我的 CarView 使用 Car 作为模型:

 <div class="carRow">               

        <%--   Color--%>
        <%=Html.CustomLabelFor(model => model.Color)%>
        <%= Html.TextBox(Model.Color) %>

         <%--   Name--%>
        <%=Html.CustomLabelFor(model => model.Name)%>
        <%= Html.TextBox(Model.Name) %>
 </div>

添加新车时,我使用 AJAX 调用,并将其添加到 html。AJAX 在控制器中使用此方法:

 public ViewResult NewCar()
    {
        return View("CarView");
    }

我的 java 脚本 ajax 调用:

            $('.addCarButton').click(function () {
            $.ajax({
                url: "<%= Url.Action("CreateCars") %>",
                cache: false,
                success: function (html) { $("#cars").append(html); }
            });
            return false;
        });

这很好地呈现了 html,但它不会将汽车添加到汽车列表中。

如何才能做到这一点?

4

3 回答 3

9

您可以查看following articleSteven Sanderson 提供的关于如何实现此功能的分步教程。

于 2013-06-06T06:30:49.243 回答
3

我意识到这是一个老问题,但是在尝试了上述关于Steven Sanderson 的 BeginCollectionItem 的建议以及其他一些潜在的解决方案之后,我并没有走得太远(新项目不会发布)。BeginCollectionItem 在理论上似乎是一个不错的解决方案,但它不会发布新项目,而且它对列表项目的格式有意想不到的影响。

该解决方案非常简单,并且不需要任何外部库(除了 JQuery)。这在 ASP.NET MVC5 中对我有用。

  1. 为行项目创建一个编辑器模板。

路径:Views/Shared/EditorTemplate/NuggetSourceDto.cshtml

@model [namespace].NuggetSourceDto

@{
    ViewBag.Title = "NuggetSourceDto";
}

<li id=@Model.Id>
    @Html.HiddenFor(t => t.Id)
    @Html.TextBoxFor(s => s.Url, new { @class = "form-control", autofocus = "autofocus" })
    <a role="button" class="glyphicon glyphicon-remove"></a>
</li>
  1. 使用上面的模板(以下运行集合并为每个项目生成 html):

在我看来:

@Html.EditorFor(m => m.NuggetSources);
  1. 当用户单击“添加行”按钮(下面我的代码中的“addSourceBtn”)时,我使用 ajax 来获取模板的 html。

MVC 控制器获取方法:

[HttpGet]
public PartialViewResult AddBlankSourcesRow()
{
    return PartialView("EditorTemplates/NuggetSourceDto", new NuggetSourceDto());
}

js处理程序:

$(document).ready(function () {
    $('#addSourceBtn').click(function () {
        var indexOfNewItem = $('#sourceList li').length;

        $.ajax({
            url: '/nugget/AddBlankSourcesRow/',
            cache: false,
            success: function (html) {
                var newItem = $(html);
                var randId = Math.random() * 10000000;
                randId = Math.floor(randId);
                newItem.attr('id', 'newSource__' + randId);
                newItem.find('input').first().attr({
                    //name: 'NuggetSources[3].Id'
                    name: 'NuggetSources[' + indexOfNewItem + '].Id',
                    id: 'NuggetSources_' + indexOfNewItem + '__Id',
                    value: randId
                });
                newItem.find('input[id^=Url]').attr({
                    name: 'NuggetSources[' + indexOfNewItem + '].Url',
                    id: 'NuggetSources_' + indexOfNewItem + '__Url'
                });
                $('#sourceList').append(newItem);
            }
        });
        return false;
    });
});

所有这一切的关键是确保新插入的元素对每个属性都有一个 name 属性,其中包括集合的名称和有效的索引:

        newItem.find('input').first().attr({
            //name: 'NuggetSources[3].Id'
            name: 'NuggetSources[' + indexOfNewItem + '].Id'
        });
        newItem.find('input[id^=Url]').attr({
            name: 'NuggetSources[' + indexOfNewItem + '].Url'
        });

没有这个,新项目在 MVC 控制器中被忽略。

此解决方案仅处理添加新行。对于删除,因为索引很重要,一种解决方案是向服务器发出删除请求,然后重新加载列表,或者只是修复 js 中现有的索引。

于 2017-07-17T01:51:14.313 回答
0

关注这个jQuery插件,专为在交易细节部分添加新元素客户端而设计

https://github.com/suraj-mahajan/Add-New-Row-jQuery-for-MVC

于 2017-06-26T07:41:07.657 回答