4

当城市输入字段模糊时,我会通过 ajax 请求获取 somne​​thing,并将其设置为与城市字段相同形式的隐藏字段的值。

$('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 事件。只要您的所有 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. 当第一个 Ajax 调用开始时,我们将旧ajaxDefer对象替换为尚未解析的新对象。使用附加的任何新功能ajaxDefer.always()将推迟到以后。

  3. 当最后一个 Ajax 调用完成时,我们调用ajaxDefer.resolve(),这会导致执行任何未执行的延迟函数。现在我们回到初始状态,任何新附加的函数都将立即执行。

  4. 当有人尝试提交表单时,创建一个匿名函数来完成这项工作并将其附加到ajaxDefer. 它会在适当的时候被执行,这取决于是否有任何未完成的 Ajax 请求。注意你的关闭。

于 2012-10-31T19:41:31.080 回答
3

使用它来检查 AJAX 调用当前是否正在使用 JQuery 进行:

if ($.active == 0) {
  ...
}
于 2014-01-13T23:30:28.863 回答
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 回答