1

我有一个页面将 JSON 发布到 cfc,并返回成功/失败消息。构建 JSON 的数组包含已更新的输入字段的 ID。我正在更改元素的背景颜色以提醒用户进行了更新,但是当用户在不离开页面的情况下发布更多更改时就会出现问题。该数组仍然包含上一篇文章中的数据,无论我尝试清除数组的内容或位置,背景的更改都会停止工作。

这是代码:

$("input").change(function(){
    theArray.push({
       'id':$(this).attr('id'),
       'value':$(this).val()
    });

});

$("#edit_button").click(function(){
    if(theArray.length >0){
        theArray.push({
           //some processing information to the cfc
        });
        theJson = JSON.stringify(theArray);
        $.post("CFCs/fund_profile.cfc",
            {
                method:"updateProfile",
                data:theJson
            },
            function(data){
            if(data.HASERROR == 1){
                $("#messageDiv").empty().html(data.MESSAGE);
            }
            else{
                $("#messageDiv").empty().html(data.MESSAGE);
                theArray.pop();//removing the cfc processing information
                for(var i = 0; i <= theArray.length; i++){
                    var $el = $("#" = theArray[i].id).parent().parent().css('background','red');
                    setTimeout(function(){
                        $el.css('background','');
                        $("#messageDiv").empty();
                    },5000);
                }
            }
         },
         "json");
        //THIS IS WHERE THE PROBLEM LIES (I THINK)
        //I HAVE TRIED THE FOLLOWING:
        var arrayLen = theArray.length;
        for(var j = 0;j <= arrayLen; j++){
            theArray.pop();
        }//DOESN'T WORK

        theArray.length = 0;
        //DOESN'T WORK

        for(var j = 0;j <= arrayLen; j++){
            theArray.shift();
        }//DOESN'T WORK
    }
});

如果我删除代码以清除数组,则会发生背景更改,但数组永远不会丢失该元素,并且始终会显示该元素正在更新。如果我保留它,则根本不会发生背景更改。

我敢肯定,我错过了一些简单的事情,但我对此感到沮丧。

有什么想法吗?

4

2 回答 2

2

根据您发布的代码的布局(这并不完全有效,所以我担心它不是您使用的实际代码),您在错误的地方处理了 AJAX 调用的后置条件. 它在回调函数之外$.post(),因此它不会以相同的顺序发生(或不保证会发生)。请记住,AJAX 是异步的,因此您的注释表明哪些工作或不工作的代码在回调函数之前发生。

我建议$.post()尽可能保持回调函数的自主性。与其让它与 JavaScript 中的数组交互,不如让服务器在更新元素的 JSON 响应中返回一个数组。然后回调函数可以自己愉快地与这些元素交互,并且在此期间产生的回调函数的其他实例不会妨碍它。

因此,基本上,您将在$.post()回调之外保留您现在拥有的数组的清除,因此它会在 AJAX 调用之后立即发生(并且可能在所有情况下在它返回之前)。您将修改服务器端代码以返回受影响的 ID。传递给回调函数的data参数将包含这些 ID,您将使用它与 CSS 交互,而不是theArray直接使用。

于 2012-04-30T19:51:04.377 回答
1

在 if/else 语句之后的 post 语句中添加以下内容:

theArray = [];

这有效地使数组为空。无需循环遍历它。

此外,正如大卫所指出的,它必须在帖子的成功内部,而不是在它之后。

编辑:
您的 for 循环没有完全按照您的预期执行, setTimeout 应该只影响最后一个元素。要解决这个问题,请切换到 a $.each,或在 for 循环中创建一个匿名函数。

for(var i = 0; i <= theArray.length; i++){
    (function(i){
        var $el = $("#" = theArray[i].id).parent().parent().css('background','red');
        setTimeout(function(){
            $el.css('background','');
            $("#messageDiv").empty();
        },5000);
    })(i);
}

还有一点需要注意:
如果有人在第一组数据完成之前向服务器提交了第二组数据,那么由于两种情况都使用相同的数组,事情可能会变得非常混乱。大卫在他的回答中很好地谈到了这一点。也许在单击事件上,您应该立即制作数组的副本,然后清除原始数组,使其保持打开状态以供下次单击使用。

示例(可能有效,未经测试):

var theArray = [];
$("input").change(function() {
    theArray.push({
        'id': $(this).attr('id'),
        'value': $(this).val()
    });

});

$("#edit_button").click(function() {
    var myArray = $.extend([], theArray, true); // get a copy of theArray
    theArray = []; // empty theArray
    if (myArray.length > 0) {
        myArray.push({
            //some processing information to the cfc
        });
        theJson = JSON.stringify(myArray);
        $.post("CFCs/fund_profile.cfc", {
            method: "updateProfile",
            data: theJson
        }, function(data) {
            if (data.HASERROR == 1) {
                $("#messageDiv").empty().html(data.MESSAGE);
            }
            else {
                $("#messageDiv").empty().html(data.MESSAGE);
                myArray.pop(); //removing the cfc processing information
                var $el = $([]);
                for (var i = 0; i <= myArray.length; i++) {
                    $el.add("#" = myArray[i].id);
                }
                $el = $el.parent().parent().css('background','red');
                setTimeout(function(){
                    $el.css('background','');
                    $("#messageDiv").empty();
                },5000);
            }
        }, "json");
    }
});

在最后一条语句中编辑更新的 for 循环,应该更容易理解。

于 2012-04-30T19:56:54.310 回答