在同步ajax上显示等待对话框

时间:2017-08-01 22:50:52

标签: javascript jquery ajax synchronous smart-wizard

我希望在创建同步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的新人。

抱歉英文不好

1 个答案:

答案 0 :(得分:0)

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

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

幸运的是,即使插件本身不支持异步,但要实现这一点非常简单。基本上,您需要做的是:

  • false回调
  • 返回onLeaveStep
  • 建立履行成功验证的承诺,或在失败时拒绝,
  • 从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()需要重复执行step1验证,那么您需要再次调用validateStep1().then(...),或者从先前缓存的承诺链接。

正如您所看到的,上面的某些方面是不完整的,所以还有一些工作要做。