4

我有一个表,我已经动态地添加/删除了行。该表包含将作为集合回发到 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 我删除了一行,此时表有 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 不在发布数据中,则将其从数据库中删除”,这样所有集合操作都可以完全在客户端在这个非常沉重的页面上节省不断的回发。

所以我开始在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]替换名称属性中的[]”?

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

编辑:

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

如果我获取名称属性值并“遍历字符”,直到找到第一个“[”和下一个“]”,然后替换其间的所有内容,它应该可以解决我的问题,但是 IE 上的这种类型的东西可能慢得要命.

任何人都有一个简洁的“只需调用这个聪明的函数”类型的答案吗?(如果有的话)。

编辑2:

哇,我真的要看起来更努力......我现在感觉多么愚蠢有两个原因(不看和正则表达式是一个明显的解决方案)

JQuery:如何在某些字符之间全部替换?

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

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

4

2 回答 2

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

如果每一行中有多个输入,而您只想更新一个,则考虑使用“以”开头的 jQuery 选择器:http ://api.jquery.com/attribute-starts-with-selector/ 。

于 2013-05-04T14:09:47.407 回答
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 ++;
    });
});

这应该删除该行并更新剩余行中每个输入的所有索引,以便它们再次正确递增(因此将被模型绑定器正确绑定)。此外,它应该仅限于当前表。这是在行动。

于 2013-05-04T14:49:59.493 回答