4

市区町村の入力フィールドがぼやけている場合、ajax リクエストを介して何かを取得し、それを市区町村フィールドが存在する同じフォームの非表示フィールドの値として設定します。

$('input#city').on('blur', function() {
    $.ajax({
        url: 'get/something?param=val',
        success: function(response) {
            $('input:hidden[name="something"]').val(response);
        }
    });
});

ユーザーが都市フィールドをぼやけた直後にフォームを送信すると、レイテンシーが原因で非表示フィールドが入力されないことがあります。これは、相手側の SQL に時間がかかりすぎるためです。

これらの両方のフィールドが入っているフォームも ajax 経由で送信されます。

$('form#find-users').on('submit', function() {
    if(NO_AJAX_CURRENTLY_RUNNING_ON_PAGE) {
        // do stuff
    }
});

ページでajaxが実行されていないかどうかを検出する方法は? これにより、都市の ajax が完了し、フォームが処理される前に非表示のフィールドにデータが入力されていることが保証されます。

編集

実際にはそうではなく、フォームが送信されないようにするだけです。しかし、それを検出できれば、setInterval を使用して、ajax が完成するまでそのコードを実行し続けることができます。理想的には、jQuery には、他の ajax が完了するまで待機してから送信するものがあります。

4

5 に答える 5

13

jQuery のAjax Eventsを使用します。すべての Ajax 呼び出しが jQuery を使用して生成されている限り、未処理の Ajax 呼び出しがあるかどうかを知る方法があります。

$(document).ready(function() {
    var ajaxBusy = false;

    $(document).ajaxStart( function() { 
        ajaxBusy = true; 
    }).ajaxStop( function() {
        ajaxBusy = false;
    });
});

編集:

これで、「実行中の Ajax 呼び出しがあるかどうかを知るにはどうすればよいですか?」という直接の質問に答えることができます。

または、ぼかしハンドラーを実行するときにフォームの送信ボタンを無効にし、完了したら再度有効にすることもできます。

$('input#city').on('blur', function() {
    var submit = $(this).closest('form').find(':submit:enabled');
    submit.prop('disabled', true);
    $.ajax('get/something?param=val').done(function(response) {
        $('input:hidden[name="something"]').val(response);
    }).always(function() {
        submit.prop('disabled', false);
    });
});

編集2:

したがって、現在の Ajax 呼び出しがすべて完了するまで、フォームの送信を遅らせたいところです。ユーザーが送信ボタンをクリックできるようにしますが、保留中の Ajax 呼び出しがある場合、すぐには何もしません。

これを支援するためにDeferredオブジェクトを使用できます。

$(document).ready(function() {
    var ajaxDefer = $.Deferred().resolve();

    $(document).ajaxStart( function() { 
        ajaxDefer = $.Deferred(); 
    }).ajaxStop( function() {
        ajaxDefer.resolve();
    });

    $('form#find-users').on('submit', function() {
        ajaxDefer.always(function() {
            // Code here will always be executed as soon as there are no 
            // Ajax calls running.
            // this points to the deferred object (ajaxDefer), so use the closure
            // to carry over any variables you need.
        });
    });
});
  1. ajaxDefer始めたばかりのときは、オブジェクトを解決済みの状態に設定します。つまり、 を使用してアタッチされた関数.always()はすぐに実行されます。

  2. ajaxDefer最初の Ajax 呼び出しが開始されると、古いオブジェクトが解決されていない新しいオブジェクトに置き換えられます。を使用して追加された新しい関数ajaxDefer.always()は、後で延期されます。

  3. 最後の Ajax 呼び出しが完了したら、 を呼び出しますajaxDefer.resolve()。これにより、実行されていない遅延関数が実行されます。これで、新しくアタッチされた関数がすぐに実行される初期状態に戻りました。

  4. 誰かがフォームを送信しようとすると、その作業を行う匿名関数を作成して に添付しajaxDeferます。未処理の Ajax リクエストがあるかどうかに応じて、必要に応じて実行されます。閉鎖に注意してください。

于 2012-10-31T19:41:31.080 に答える
1

変数をグローバル名前空間に配置し、おそらく名前ajaxLockを付けて、AJAXの開始時にオンに切り替え、応答が来るときにオフに切り替えることができます。次に、送信を許可する前に確認してください。

何かのようなもの

var ajaxLock = 1;
$('input#city').on('blur', function() {
$.ajax({
    url: 'get/something?param=val',
    success: function(response) {
        $('input:hidden[name="something"]').val(response);
        ajaxLock = 0;
    }
    });
});
于 2012-10-31T19:33:25.373 に答える
1

あなたが提案したようにロック変数を使用してください:

$('input#city').on('blur', function() {
    window.AJAX_CURRENTLY_RUNNING_ON_PAGE = true;
    $.ajax({
        url: 'get/something?param=val',
        success: function(response) {
            $('input:hidden[name="something"]').val(response);
        },
        complete: function() { window.AJAX_CURRENTLY_RUNNING_ON_PAGE = false; }
    });
});

$('form#find-users').on('submit', function() {
    if(window.AJAX_CURRENTLY_RUNNING_ON_PAGE) {
        return;
    }
    //dostuff
});
于 2012-10-31T19:36:13.473 に答える
0

この状況で私ができることは、ブロックUIのようなプラグインを使用するか、フォーム送信ボタンを無効にすることです。その理由は、デザインでインタラクティブにする必要があるためです。フォーム送信をロックできるかもしれませんが、メッセージまたはモーダルグレーアウト

于 2012-10-31T19:38:19.250 に答える