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 が含まれており、theArray直接使用する代わりにそれを使用して CSS と対話します。

于 2012-04-30T19:51:04.377 に答える
1

if/else ステートメントの後の post ステートメント内にこれを追加します。

theArray = [];

それは効果的に配列を空にします。ループする必要はありません。

また、デビッドが指摘したように、それはポストの成功の後ではなく、ポストの成功の中にある必要があります.

編集:
for ループが期待どおりに実行されていないため、setTimeout は最後の要素にのみ影響するはずです。それを解決するには、に切り替える$.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);
}

もう 1 つ注意:
最初のデータ セットが完了する前に誰かが 2 番目のデータ セットをサーバーに送信すると、両方のケースで同じ配列が使用されるため、非常に混乱する可能性があります。デビッドは、彼の答えでそれについてかなりうまく触れました。おそらく、クリックイベントで、すぐに配列のコピーを作成してから、元の配列をクリアし、次のクリックで使用できるように開いたままにする必要があります。

例 (動作する可能性がありますが、テストされていません):

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 に答える