Jquery 在MVC中编辑可变长度的项目列表

Jquery 在MVC中编辑可变长度的项目列表,jquery,asp.net-mvc,Jquery,Asp.net Mvc,我正在开发一个MVC web应用程序,需要一个可变长度的项目列表。用户应该能够通过保存来添加/编辑和删除行,并对所有行执行批更新 我从两篇博文开始工作,这两篇博文几乎涵盖了大部分工作,所以都归功于史蒂夫·桑德森 我的看法如下 <% using (Html.BeginForm()) { %> <div id="placeholder"> <% for (int i = 0; i < Model.Count(); i++) {

我正在开发一个MVC web应用程序,需要一个可变长度的项目列表。用户应该能够通过保存来添加/编辑和删除行,并对所有行执行批更新

我从两篇博文开始工作,这两篇博文几乎涵盖了大部分工作,所以都归功于史蒂夫·桑德森


我的看法如下

<% using (Html.BeginForm()) { %>

<div id="placeholder">
    <% for (int i = 0; i < Model.Count(); i++)
       {
           ViewData["index"] = i;
           Html.RenderPartial("ProfileItemLine", Model.ElementAt(i), new ViewDataDictionary(ViewData) {
            {"prefix", "items"}
        });
       } 
    %>
</div>

<div id="addProfileItem">
    <a href="" id="addItem">Add another item</a>
</div>

<input type="submit" value="Save changes" />

<% } %>

并使用jQuery处理添加和删除

    $(document).ready(function() {

    var nextIndex = <%=ViewData.Model.Count()%>;
    setRemoveLinks();

    $('#addItem').click(function() {
        var action = '/Profile/BlankItemLine?index=' + nextIndex;
        $.get(action, 'html', function(lineItemHtml) {
            $('#placeholder').append(lineItemHtml);
            setRemoveLinks();
        });
        nextIndex++;
        return false;
    });
});

function setRemoveLinks() {
    $('a.removeItem').click(function() {
        $(this).parent('div').remove();
        return false;
    });
}
$(文档).ready(函数(){
var-nextIndex=;
setRemoveLinks();
$('#addItem')。单击(函数(){
var action='/Profile/BlankItemLine?index='+nextIndex;
$.get(操作,'html',函数(lineItemHtml){
$(“#占位符”).append(lineItemHtml);
setRemoveLinks();
});
nextIndex++;
返回false;
});
});
函数setRemoveLinks(){
$('a.removietem')。单击(函数(){
$(this.parent('div').remove();
返回false;
});
}
ProfileItemLine ViewUserControl如下所示减去格式和纯文本

<div>
<% var fieldPrefix = string.Format("{0}[{1}].", ViewData["prefix"], ViewData.Model.Sequence); %>
<%= Html.Hidden(fieldPrefix + "ProfileItemId", ViewData.Model.ProfileItemId)%>
<%= Html.TextBox(fieldPrefix + "Title", ViewData.Model.Title, new { size = "30"})%>
<%= Html.CheckBox(fieldPrefix + "IsHighlighted", ViewData.Model.IsHighlighted)%>   
<a href="" class="removeItem">Delete</a></div>

到目前为止还不错,列表正确绑定到模型,只要我只添加项,它也可以工作

问题与删除有关。delete可以工作并删除正确的行,但我丢失了表单提交上的所有绑定。在Steve的帖子中,他提到RC已经改变了模型绑定的工作方式,它要求所有索引都处于一个不间断的升序中

Steve列出了一些代码以开始工作,其中包括在表单提交时重新排序列表,但它在“var controls=”行中抛出了一个异常,方法不受支持

$(function() {
$("form").submit(function() {
    // Normalize the sequence before submitting the form
    ensureControlGroupsInNumericalOrder("#placeholder div", "items");
});});

function ensureControlGroupsInNumericalOrder(groupSelector, controlNamePrefix) {
var groups = $(groupSelector);
var nameToEndOfIndexRegex = new RegExp(controlNamePrefix + "\\[\\d+");
for (var seq = 0; seq < groups.length; seq++) {
    var controls = $("*[name~=" + controlNamePrefix + "\[]", groups[seq]);
    for (var c = 0; c < controls.length; c++)
        controls[c].name = controls[c].name.replace(nameToEndOfIndexRegex, controlNamePrefix + "[" + seq);
}}
$(函数(){
$(“表格”)。提交(函数(){
//在提交表单之前规范化序列
确保控制组数字领主(“占位符div”,“items”);
});});
函数ensureControlGroupsInNumericalOrder(groupSelector,controlNamePrefix){
变量组=$(组选择器);
var nameToEndOfIndexRegex=新的RegExp(controlNamePrefix+“\\[\\d+”);
对于(var-seq=0;seq
两次删除索引1和2后的html输出示例

    <div id="placeholder">
<div>
    <input id="items[0]_ProfileItemId" name="items[0].ProfileItemId" type="hidden" value="0fd3a3f5-907e-4eb1-8f69-26e3840e5e12" />
    <input id="items[0]_Title" name="items[0].Title" size="30" type="text" value="Number 1" />
    <input id="items[0]_IsHighlighted" name="items[0].IsHighlighted" type="checkbox" value="true" />
    <input name="items[0].IsHighlighted" type="hidden" value="false" />   
    <a href="" class="removeItem">Delete</a>  
</div>
<div>
    <input id="items[3]_ProfileItemId" name="items[3].ProfileItemId" type="hidden" value="0fa1a3f5-907e-4eb1-8f69-26e3840e5e12" />
    <input id="items[3]_Title" name="items[3].Title" size="30" type="text" value="Number 3" />
    <input id="items[3]_IsHighlighted" name="items[3].IsHighlighted" type="checkbox" value="true" />
    <input name="items[3].IsHighlighted" type="hidden" value="false" />   
    <a href="" class="removeItem">Delete</a>  
</div>
</div>

我在表单提交时将模型绑定到IEnumerable,在本例中,我只会取回第一个项,而不会取回第二个项,因为它是项[3],而不是项

publicActionResult编辑项(Guid id,IEnumerable项)
{
if(ModelState.IsValid)
{
//保存项目
}
if(ModelState.IsValid)
返回操作(“索引”);
其他的
返回视图(项目);
}
我还在研究jQuery和正则表达式,所以我想知道是否有人能给我一个解决方案


提前感谢

为什么您需要所有单个元素信息

使用它不是更明智吗

<div id="div1">
我总是这样:)


您可以在html创建循环中设置div和rel的编号,因此顺序总是正确的。

为什么需要所有单独的元素信息

使用它不是更明智吗

<div id="div1">
我总是这样:)


您可以在html创建循环中生成div和rel的数字,因此顺序总是正确的。

Hi,这在我的场景中有效吗?我认为单个元素信息与绑定到列表的模型相关,因此它是必需的。请看,我的要求是,这是一个批处理操作,因此无法对db进行单独调用。因此呃,我还没有尝试你的解决方案,我不确定这是否是答案。你有一个有效的例子吗?嗨,这在我的场景中会起作用吗?我认为单个元素信息与绑定到列表的模型相关,所以它是必需的。我的要求是,这是一个批处理操作,因此无法单独调用db。因此,尽管我还没有尝试你的方法解决方案我不确定这是不是答案。你有一个有效的例子吗?
<a rel="1" id="item + item id (not per se 1 )" class="delete">delete</a>
$('.delete').bind('click',function(){ 
  $('#div' + $(this).attr('rel') ).remove();
  // plus delete call to db ?
});