【问题标题】:Show waiting dialog on synchronous ajax在同步 ajax 上显示等待对话框
【发布时间】:2017-08-01 22:50:51
【问题描述】:

我想在制作同步 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 的新手。

抱歉英语不好

【问题讨论】:

  • 为什么要使用同步ajax?
  • 不使用同步jax的简单解决方案怎么样?改用ajax。无论如何,您都在使用所有必要的回调。
  • 顺便说一句,jQuery 中没有 failure 回调。只有error
  • @JoshBeam 我正在使用同步 ajax,因为当我不使用它时,智能向导不会等待 ajax 完成,而是返回 res 的 false 值并且不更改步骤。
  • 不支持异步的向导不太聪明……

标签: javascript jquery ajax synchronous smart-wizard


【解决方案1】:

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

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

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

  • onLeaveStep回调返回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(...),或者从之前缓存的promise 中链接。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 2013-07-14
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多