同步显示等待对话框 ajax

Show waiting dialog on synchronous ajax

我想在进行同步 ajax 时显示等待对话框。 我使用智能向导,要在第一步和下一步之间切换,我必须验证一些数据才能做到这一点,我必须让 3 ajax 一个接一个地调用,完成后我想显示一个等待对话框.这就是我正在做的。

if (indexes.fromStep==1) {  
    res=false;  
    var validatorResult = validator.checkAll($("#install_modbus_form"))
    if (validatorResult) {          
        $("#modal_loader").modal()      
        $.ajax({
            type: "post",
            url: url1, 
            async: false,            
            dataType: "json",   
            data:{
                data
            },     
            success: function(response)
            { 
                if (response.success) 
                {
                    $.ajax({
                        type: "post",
                        url: url2, 
                        async: false,            
                        dataType: "json",   
                        data:{
                            data
                        },     
                        success: function(response)
                        { 
                            if (response.success) 
                            {
                                $.ajax({
                                    type: "post",
                                    url: url3, 
                                    async: false,            
                                    dataType: "json",   
                                    data:{
                                        data
                                    },     
                                    success: function(response)
                                    { 
                                        if (response.success) 
                                        {
                                            //make magic here
                                            res=true;
                                        }
                                    },
                                    failure:function() 
                                    {
                                        waitingDialog.hide()
                                        res=false
                                    },
                                    error:function(a,b,c) {
                                        waitingDialog.hide()
                                        res=false
                                    }
                                )
                            }
                        },
                        failure:function() 
                        {
                            waitingDialog.hide()
                            res=false
                        },
                        error:function(a,b,c) {
                            waitingDialog.hide()
                            res=false
                        }
                    )
                }
            },
            failure:function() 
            {
                waitingDialog.hide()
                res=false
            },
            error:function(a,b,c) {
                waitingDialog.hide()
                res=false
            }
        )
        $("#modal_loader").modal('hide')        
        return res;//if true change step 
    }
}

我试过使用 beforeSend 来显示等待对话框,我也试过使用 setTimeout 但是等待对话框没有显示,智能向导也没有前进

希望你能帮忙,我是 jquery 的新人。

抱歉英语不好

假设您使用的是jQuery-Smart-Wizard,解决方案在于:

  • 构建您的 onLeaveStep 事件处理程序,和(或包括)
  • 问题中显示的验证码的修改版本。

幸运的是,尽管该插件本身不支持异步,但实现起来相当简单。本质上,您需要做的是:

  • onLeaveStep 回调到 return false
  • 建立一个承诺,在成功验证时履行,或在失败时拒绝,
  • 从 promise 的成功处理程序调用 .smartWizard('goForward')
  • 从 promise 的错误处理程序中调用 .smartWizard('showError')

基于 smartWizard 的 ReadMe.md,这里有一个用于执行同步和异步验证的框架:

$(document).ready(function() {
    var waitingDialog = $('#whatever'); // ???

    // Smart Wizard         
    $('#wizard').smartWizard({
        onLeaveStep: leaveAStepCallback,
        onFinish: onFinishCallback
    });

    function leaveAStepCallback(obj, context) {
        alert("Leaving step " + context.fromStep + " to go to step " + context.toStep);
        var returnValue;
        switch(context.fromStep) {
            case 1: // asynchronous
                if (validator.checkAll($("#install_modbus_form"))) {
                    $("#modal_loader").modal();
                    waitingDialog.show();
                    validateStep1() // validateStep1() returns a promise
                    .then(function() {
                        // You will arrive here only if all three ajax calls were successful and all three responded with a truthy `response.success`.
                        $('#wizard').smartWizard('goForward'); // advance to next step
                    }, function(e) {
                        // You will arrive here on validation failure
                        $('#wizard').smartWizard('showError', e.message); // something went wrong
                    }).always(function() {
                        // You will arrive here on validation success or failure
                        waitingDialog.hide(); // the waiting is over
                        $("#modal_loader").modal('hide'); // ???
                    });
                } else {
                    $('#wizard').smartWizard('showError', 'validator.checkAll() failed');
                }
                returnValue = false; // *must* return false to remain at step 1. If validation is successful, `.smartWizard('goForward')` will be executed later (see above).
            break;
            case 2: // synchronous
                returnValue = validateStep2(); // validateStep2() returns true of false
            break;
            case 3:
                ...
            break;
        }
        return returnValue; // true or false
    }

    // And here's the all-important `validateStep1()` :
    function validateStep1() {
        var sequence = [
            { url: 'url/1', data: {...} },
            { url: 'url/2', data: {...} },
            { url: 'url/3', data: {...} }
        ];

        return sequence.reduce(function(promise, item, i) {
            return promise.then(function() {
                return $.ajax({
                    'type': 'post',
                    'url': item.url,
                    'dataType': 'json',
                    'data': item.data
                }).then(function(response, textStatus, jqXHR) {
                    return response.success ? response : $.Deferred().reject(jqXHR, 'response.success not truthy at validation stage ' + i); // note: need to mimic jQuery.ajax's error signature.
                });
            });
        }, $.when()) // starter promise for the reduction
        .then(null, function(jqXHR, textStatus, errorThrown) {
            return $.Deferred().reject(new Error(textStatus || errorThrown));
        });
    }

    function validateStep2() {
        // if validation here is synchronous, then return true of false
        if(....) {
            return true;
        } else {
            return false;
        }
    }
    function validateStep3() {
        ...
    }
    // etc.

    function onFinishCallback(objs, context) {
        if(validateAllSteps()) {
            $('form').submit();
        }
    }

    function validateAllSteps() {
        var isStepValid = true;
        // all step validation logic     
        return isStepValid;
    }          
});

备注:

  • 分支逻辑在onLeaveStep回调中。
  • validateStep1() 使用链式承诺模式对三个 ajax 调用进行排序。
  • 如果 validateAllSteps() 需要重复第 1 步验证,那么您将需要再次调用 validateStep1().then(...),或者从之前缓存的承诺中链接。

如您所见,上面的某些方面还不完整,因此还有一些工作要做。