如何使用Razor和.NET Core将项添加到ViewModel的列表中?

Daa*_*ath 7 c# asp.net-mvc viewmodel razor asp.net-mvc-4

所以这是我的情况.

假设我有一个名为TheView.cshtml. TheView.cshtmlViewModel的视图TheViewModel.cs.在TheViewModel.cs,驻留一个TheObject被调用的对象()的列表TheObjectList.

我有一个TheObject被调用的编辑器模板TheObject.cshtml.使用此编辑器模板,我可以简单地显示TheObjectListwith 中的所有项目@Html.EditorFor(model => model.TheObjectList).

但是,现在我想动态地将对象添加到此列表中.我有一个AJAX函数,它调用一个简单的局部视图来给用户一个空白行来添加一个新的" TheObject",但是,TheObject我动态添加的任何新函数都不被认为是原始的一部分TheObjectList.

这是因为原始中的每个项目TheObjectList都是根据原始列表中的索引创建的,而每个新的动态TheObject都是在没有前缀的情况下创建的,因此Razor不会将其视为列表的一部分.

有没有解决的办法?

TheView.cshtml

@model Models.ViewModels.TheViewModel

<table id="Table">
    <tbody>
        @Html.EditorFor(m => m.TheObjectList);
    </tbody>
</table>

<button id="AddObject" type="button" class="btn btn-primary">Add Object</button>
Run Code Online (Sandbox Code Playgroud)

TheViewModel.cs

public class TheViewModel
{
    public List<TheObject> TheObjectList { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

AddObject控制器方法

public IActionResult AddObject()
{
   return PartialView("_EmptyRow", new TheObject());
}
Run Code Online (Sandbox Code Playgroud)

添加对象的AJAX方法

$('#AddObject').click(function () {
    $.ajax({
        url: 'AddObject',
        cache: false,
        success: function (data) {
            $('#Table > tbody').append(data);
        },
        error: function (a, b, c) {
            alert(a + " " + b + " " + c);
        }
     });
});
Run Code Online (Sandbox Code Playgroud)

Shy*_*yju 14

您基本上需要生成/返回标记,该标记与编辑器模板为表单字段生成的内容相同,但元素索引除外.您需要从客户端传递索引,该索引将是表单字段名称的一部分.

假设你的编辑器模板如下所示,你的TheObject有一个GroupName属性

@model TheObject
<div>
    @Html.HiddenFor(x => x.GroupName)
    @Html.TextBoxFor(s=>s.GroupName,new {@class="thingRow"})
</div>
Run Code Online (Sandbox Code Playgroud)

现在,当您使用当前代码渲染页面时,编辑器模板将生成这样的输入字段

<input class="thingRow" id="TheObjectList_0__GroupName" 
                           name="TheObjectList[0].GroupName" type="text" value="Something">
Run Code Online (Sandbox Code Playgroud)

其中0将替换为TheObjectList集合中项目的索引.

现在假设您已经在集合中有5个项目,因此当用户单击添加按钮时,您希望生成如上所述的标记,除非0将替换为5(对于第六个项目).因此,让我们更新ajax调用以包含当前的项目数.

$('#AddObject').click(function () {
    var i = $(".thingRow").length;
    $.ajax({
        url: 'AddObject?index=' + i,
        success: function (data) {
            $('#Table > tbody').append(data);
        },
        error: function (a, b, c) {
            console.log(a, b, c);
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

这意味着,我们需要在action方法中接受索引值.由于我们需要将此索引值从action方法传递到我们的视图以构建输入字段名称值,因此我向您的类添加了一个属性Index

public ActionResult AddObject(int index)
{
    return PartialView("_EmptyRow", new TheObject { Index = index});
}
Run Code Online (Sandbox Code Playgroud)

现在在_EmptyRow局部视图中,

@model TheObject
<input id="TheObjectList_@(Model.Index)__GroupName"class="thingRow" 
             name="TheObjectList[@(Model.Index)].GroupName"  type="text" value=""/>
Run Code Online (Sandbox Code Playgroud)

现在,当您提交表单时,模型绑定将适用于这些动态添加的项目,假设您在表单中包含表格.

@model TheViewModel
@using (Html.BeginForm())
{   
    <table id="Table">
        <tbody>
            @Html.EditorFor(m => m.TheObjectList);
        </tbody>
    </table>
    <button id="AddObject" type="button" class="btn btn-primary">Add Object</button>
    <button type="submit" class="btn btn-primary">Save</button>
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿,男人还有一个问题 - 也许你可以帮助我.添加效果很好,但是我想说我想从列表中删除.如果我从列表中间删除一个,则其后的每个其他项也会被删除 (4认同)
  • 对于删除,您需要编写一些javascript,它会更新所有以下元素的索引...或者作为第二个选项:只需添加一个带有deleted = true的隐藏输入元素,并在提交表单后处理删除 (4认同)
  • 哦,天啊,如果我能送你一包12包啤酒,我愿意.我整天坚持这一点,你的回答是如此明显,我无法相信我没有想到它.非常感谢 - 我希望我能给你更多的声誉.再次感谢!! (3认同)