1

先日の質問に続いて、私はもう 1 つの問題に遭遇しましたが、今では頭をぶつけるのに何時間も費やしました。

ほとんどの場合、SUCCESS フォームを送信するのに問題があります。私もこれを試しました:

jQueryフォーム送信

半機能フィドルのコードは次のとおりです。

http://jsfiddle.net/ZcgqV/

基本的に何が起こるかは次のとおりです。

  1. (クリックではなく) onSubmit を介してメソッドをフォームの送信にバインドします。
  2. 送信時に、jQuery .ajax() 呼び出しを介してリモート サーバーを呼び出します。
  3. 応答が「PENDING」の場合は、1 秒ごとに 9 回再試行します
  4. 失敗した場合、フォームを送信しないでください
  5. 成功したら、フォームを送信します

何を試しても、ループに入ることなく必要なときにフォームを送信したり、リモートサーバーを試行しているときにすぐに送信したりできません。

~フラストレーションのない試行錯誤の100の失敗はあなたのもの...

フィドルが嫌いな場合の直接のコードは次のとおりです。

var retries = 0;
var success = false;
var token = "toki wartooth is not a bumblebee";

$(document).ready(function() {
    // Attach the action to the form
    $('#tehForm').attr('onSubmit', 'onsubmit_action(event)');
});

function async(fn) {
    setTimeout(fn, 1000);
}

function pollServer() {
    $.ajax({
        type: "POST",
        cache: "false",
        url: "/remoteCall",
        dataType: "json",
        data: {
            ref_token: token
        }
    }).done(function(data, code, jqXHR) {

        switch (data.status) {
        case "SUCCESS":
            alert("Success");
            success = true;

            // --> HERE IS WHERE I WANT THE FORM TO SUBMIT <--

            break;

        case "PENDING":
            if (retries < 9) {
                retries += 1;
                async(function() {
                    pollServer();
                });
            } else {
                alert("Failed after 9 tries");
            }
            break;

        case "ERROR":
            alert("Error");
            break;

        default:
            alert("Some kind of horrible error occurred");
            break;
        }

    }).fail(function(jqXHR, textStatus) {
        var statusCode = jqXHR.status;
        alert("Request failed: " + statusCode + " " + textStatus);
    });

}

function onsubmit_action(event) {
        pollServer();
        if (success === false) {
            // RETURN FALSE DIDN'T WORK, SO I FOUND THIS
            event.preventDefault();
        }
}​

編集:

繰り返しますが、ここでの本当の問題は、フォームの送信を停止することです。成功したら、フォームを送信したい。現在、SUCCESS で .submit() を使用すると、AJAX が再度呼び出され、プロセスが最初からやり直されます。私が欲しいのは、フォームのアクションが成功した場合にのみ発生することです。

4

3 に答える 3

3

元のコードをできるだけ多く使用するようにしています。ここに解決策があります:

ポストバック付きのポストフォーム http://jsfiddle.net/tpm7v/4/

Ajax 経由でフォームを投稿 http://jsfiddle.net/tpm7v/5/

    var retries = 0,
    token = "toki wartooth is not a bumblebee",
    sendRequest,
    handelResponse,
    postFormToServer,
    $theForm = $('#tehForm');

$(document).ready(function() {
    // Attach the action to the form
    $theForm.bind('submit', onsubmit_action);
});

sendRequest = function() {
    $.ajax({
        type: "POST",
        cache: "false",
        url: "/remoteCall",
        dataType: "json",
        data: {
            ref_token: token
        },
        success: handelResponse
    });
};

postFormToServer = function() {
    $.ajax({
        type: "POST",
        cache: "false",
        url: "/remoteCallToTakFormData",
        dataType: "json",
        data: $form.serialize(),
        success: function() {
            alert('success!');
        }
    });
};

handelResponse = function(data, code, jqXHR) {
    switch (data.status) {
        case "SUCCESS":
            postFormToServer();
            break;

        case "PENDING":
            if (retries < 9) {
                retries += 1;
                setTimeout(sendRequest , 1000);
            } else {
                alert("Failed after 9 tries");
            }
            break;

        case "ERROR":
            alert("Error");
            break;

        default:
            alert("Some kind of horrible error occurred");
            break;
        }
};

function onsubmit_action(evt) {
    evt.preventDefault();
    sendRequest();
}
​
​

提供されたコードから離れることを覚えておいてください。実際の実装で動作するようにこれを移植できるはずです。https://github.com/webadvanced/takeCommandのようなものを試して、すべての Ajax 呼び出しをクリーンアップすることもできます。

于 2012-08-16T23:44:51.137 に答える
0

詳細については、上記の私のコメントを参照してください。ただし、ここで発生している問題は次のとおりだと思います。

pollServer() が起動するたびに、別の ajax 呼び出しを実行するだけでなく、再試行ループに基づいて毎秒 9 回の ajax 呼び出しを実行する準備をしています。次に、async() メソッドを使用して別の pollServer() 呼び出しを設定しているため、基本的に ajax 呼び出しを制御不能にしています。再試行ループから ajax 呼び出しを取得したい場合は、少なくとも 1 秒に 1 リクエストのみを取得する必要があります。1、2、3 などではありません。コードを間違って読んだ可能性がありますが、これが私のベストですあなたが見ているものを推測してください。

更新: 説明が明確であるかどうかわからないので、追加情報を追加すると思いました。基本的に、pollServer() が呼び出されて PENDING 応答を受け取るたびに、async が呼び出され、setTimeout() が登録されます。setTimeout() は毎秒実行され続け、pollServer() を実行します。これにより asynch が呼び出され、別の setTimeout() も毎秒実行されます。これで、サーバーからの応答としてまだ PENDING を取得していると仮定して、それぞれが setTimeout() を呼び出す 2 つの関数ができました。したがって、呼び出しが 2 回失敗した後、毎秒 ajax 呼び出し (および新しい setTimeout) を起動する 4 つの setTimeout() 呼び出しがあります。

于 2012-08-16T23:29:20.817 に答える
0

まず、次のようにする必要があります: $('#tehForm').submit(onsubmit_action);or$('#tehForm').on("submit",onsubmit_action);またはそのようなもの。関数を渡すために文字列形式を使用しないでください。それは邪悪な eval ステートメントを使用します。

次に、POST の後、データは既に送信されています。それが投稿の理由です。done セクションであらゆる種類のエラー処理が必要なのはなぜですか。Fail はエラー処理を処理する必要があります。

タイムアウト後に再試行する方法について尋ねている場合は、これを試してください: jQuery.post() でタイムアウトを確認することは可能ですか?

タイムアウトは失敗すると思います。

だからこれを試してください:

var retries = 0,
    max_tries = 9,
    success = false,
    token = "toki wartooth is not a bumblebee";

$(document).ready(function() {
    // Attach the action to the form
    $('#tehForm').on("submit",submit_the_form);
});

function submit_the_form(e){
   var dfd = $.ajax({
       url : "sendTokenPolling", 
       data : {"token":token},
       timeout : 5000 //you may want 1000, but I really think that is too short
    });
   dfd.done(function(){
      //success, form posted
   });
   dfd.fail(function(){
      //did not work/timedout
      if (retries < max_tries){
         retries += 1;
         submit_the_form(e);
      }
   });
}
于 2012-08-16T23:39:30.983 に答える