【问题标题】:JQuery MVC collection name attributesJQuery MVC 集合名称属性
【发布时间】:2013-04-28 19:23:30
【问题描述】:

我有一个表,我已经动态地添加/删除了行。 该表包含将作为集合回发到 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] 替换 name 属性中的 []”?

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

编辑:

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

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

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

编辑 2:

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

JQuery: how to replace all between certain characters?

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

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

【问题讨论】:

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


    【解决方案1】:

    这应该适合你:

    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/

    【讨论】:

    • 这就是我要去的地方,但由于某种原因,我似乎无法让它工作。
    • 究竟是什么“不起作用”?这也是我想到的解决方案。
    • 大声笑我们都犯的第一个错误......是第二个选择器正在查看文档范围。设置 var inputFields
    • 刚刚更新它以在当前行上使用.find() 选择器。
    • ive 还注意到由于某种原因 jquery 似乎忽略了 tbody / thead 元素
    【解决方案2】:

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

    假设您在每一行都有一个类为 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 ++;
        });
    });
    

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

    【讨论】:

    • 我喜欢 Ant 这个解决方案,它完美地涵盖了细节 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多