JQuery MVC集合名称属性

时间:2013-05-04 13:50:36

标签: c# jquery asp.net-mvc html5

我有一张桌子,我已经动态添加/删除了行。 该表包含将作为集合发布回MVC的字段。 在这种情况下,使用jquery更新表意味着我需要包含不完整集合的集合,例如......

function add() {
     $.ajax({
            url: "GetRow",
            type: 'post',
            dataType: 'html',
            timeout: 30000,
            data: {
                RowIndex: otherRows.length,
                "Item.Property1": $("option:selected", dropDown).text(),
                "Item.Property2": $("option:selected", dropDown).val()
            },
            success: function (result) {
                var newRow = $(result);
                tableBody.append(newRow);
            }
        });
}

此函数进行ajax调用以获取mvc操作结果,该结果返回给定索引处的行结果,并另外从我的页面上的下拉列表中设置一些默认值。

现在我假设我有一个类似的函数叫做“delete”,其中使用jquery i删除一行,此时表有3行(当然忽略标题行),我要删除的行是中间一行。

这意味着我的行中的字段最终看起来像这样......

//Row 1:
<input type="text" name="SomeCollection[0].Property1" /> 

//Row 2:
   Nothing, deleted of course

//Row 3: 
<input type="text" name="SomeCollection[2].Property1" /> 

因此,如果我现在进行回发,由于id范围不一致,MVC模型绑定器将仅为我绑定项目1,而项目2(实际上是客户端删除之前的项目3)未映射。

我的想法是,我希望我的服务器逻辑做一个非常简单的“如果我的集合中的项目的id不在post数据中,从数据库中删除它”,这样所有的集合操作都可以完全客户端在这个非常繁重的页面上保存不断的回发。

所以我开始在jquery中将一个函数放在一起来解决问题......

function updateNames(table) {
    var rows = $("tr", table);
    var index = 0;

    rows.each(function () {
        var inputFields = $("input");

        inputFields.each(function (){
          //replace name="bla[<any number>].Anything" with 
          //        name="bla[" + index + "].Anything"        
        });

        index++;
    });
}

所以我的问题是......我怎么说jquery“用[index]”替换name属性中的[]?

我知道这不会解决嵌套集合/其他类似复杂场景的问题,但是一旦我解决了这个问题,我总能在以后扩展它,而我的要求还没有涉及到。

编辑:

关于我目前的思维模式的一些额外细节......好还是坏?

如果我抓住name属性值并“go the chars”直到我找到第一个“[”和下一个“]”然后替换它们之间的所有内容,它应该解决我的问题,但IE上的这种类型的东西可能地狱慢了。

任何人都有一个整洁的“只是称这个聪明的功能”类型答案? (如果有的话)。

编辑2:

<哇哇我真的要看起来更难......我现在觉得笨蛋有两个原因(不看和正则表达式是一个明显的解决方案)

JQuery: how to replace all between certain characters?

如果我能找到正确的正则表达式我已经得到了我的解决方案(也许这就是我应该问的问题,因为我一直对正则表达式的疯狂感到恼火)。

但是正则表达式的力量不能低估:)

2 个答案:

答案 0 :(得分:4)

这应该适合你:

function updateNames(table) {

    var rows = $("tr", table);
    var index = 0;

    rows.each(function () {
        var inputFields = $(this).find("input");
        inputFields.each(function (){
            var currentName = $(this).attr("name");
            $(this).attr("name", currentName.replace(/\[(.*?)\]/, '['+index+']')); 

        });
        index++;
     });
}

如果每行内有多个输入,而您只想更新一个,那么请考虑使用'starts with'jQuery选择器:http://api.jquery.com/attribute-starts-with-selector/

答案 1 :(得分:4)

虽然你已经有了一个解决方案,但我认为一个如何从头开始实现这个功能的工作演示可能会有用。

假设每行都有一个类delete的按钮,您可以通过以下方式实现此目的:

$('.delete').click(function(e) {
    // Get table body and rows
    var body = $(this).closest('tbody');

    // Remove current row
    $(this).closest('tr').remove();

    // Get new set of rows from table body
    var rows = body.find('tr')

    // Update all indeces in rows
    var re = new RegExp(/\[[0-9]+\]/);
    var index = 0;
    rows.each(function () {
        $(this).find('input').each(function (e) {
            var input = $(this).attr('name');
            if (input) {
                $(this).attr('name', input.replace(re, '['+index+']'));
            }
        });
        index ++;
    });
});

这应该删除行并更新剩余行中每个输入的所有indeces,以便它们再次正确递增(因此将由模型绑定器正确绑定)。此外,它应限于当前表。 Here it is in action.