【问题标题】:Return promise to use with ajax object返回与 ajax 对象一起使用的承诺
【发布时间】:2013-10-07 16:12:29
【问题描述】:

我有一个函数,我将 form 元素传递到其中,以便使用 AJAX 处理表单提交。

我想从我的函数返回将处理表单提交的 ajax 对象,以便我可以附加额外的done 回调——问题是我不知道如何在不创建它的情况下返回 ajax 对象(并执行它)首先。

我怎样才能用 promise 代替实际的 ajax 对象,以便我返回一些东西来附加额外的回调?

HandleModalFormSubmit: function (element) {
    var form,
    modalcontainer = $(element).closest('.modal'),
        modal = $(element).closest('.modal-dialog'),
        ajaxdata;


    if (element.is('form')) form = $(element);
    else {
        form = element.find('form');
    }

    $.validator.unobtrusive.parse(form);

    $(element).on('submit', function (event) {
        event.preventDefault();
        ajaxdata = $.ajax({
            type: form.method,
            url: form.action,
            data: $(form).serialize()
        }).done(function (data) {
            if (data.status == null) {
                modal.html(data);
            } else {
                modalcontainer.modal('hide');
            };
        }).always(function (data) {
            modal.spin(false);
            modal.fadeTo(500, 1);
        });
        modal.fadeTo(300, 0);
        modal.spin();
    });
    var returningobject = {
        element: form,
        ajax: ajaxdata
    };
    return returningobject;
}
}

编辑:这是我希望函数发生的事情

 var formobject = $Global.HandleAjaxForm(element);
                formobject.ajax.done(function(data1) {
                    if (data1.status == 'ok')
                        window.location.href = (data.redirectToUrl == null) ? "~/Dashboard" : data.redirectToUrl;
                });

【问题讨论】:

    标签: jquery ajax asynchronous promise


    【解决方案1】:

    是否可以将回调附加到函数并在 ajax done 回调中触发该回调?或者你真的需要 ajax 对象本身而不是附加一个 done() 监听器

    HandleModalFormSubmit: function (element, callBack) {
        var form,
        modalcontainer = $(element).closest('.modal'),
            modal = $(element).closest('.modal-dialog'),
            ajaxdata;
    
    
        if (element.is('form')) form = $(element);
        else {
            form = element.find('form');
        }
    
        $.validator.unobtrusive.parse(form);
    
        $(element).on('submit', function (event) {
            event.preventDefault();
            ajaxdata = $.ajax({
                type: form.method,
                url: form.action,
                data: $(form).serialize()
            }).done(function (data) {
                if (data.status == null) {
                    modal.html(data);
                } else {
                    modalcontainer.modal('hide');
                };
    
              //call the callback within the done function of the ajax object here
              if(callBack && typeof callBack == "function") callBack.call(context, params);
            }).always(function (data) {
                modal.spin(false);
                modal.fadeTo(500, 1);
            });
            modal.fadeTo(300, 0);
            modal.spin();
        });
        var returningobject = {
            element: form,
            ajax: ajaxdata
        };
        return returningobject;
    }
    }
    

    很明显,这不会给你 ajax 对象本身,但你可以插入回调并踢出你需要的任何参数。

    编辑: 您还可以返回 jquery ajax 函数本身 像这样:

    HandleFormSubmit : function(){
       return $.ajax({});
    }
    

    然后你可以像这样附加你的完成方法:

    HandleFormSubmit().done(function(){
    });
    

    【讨论】:

    • 这可以工作,但返回一个对象会更有用,这样我就可以附加不同的回调
    • 哦,我明白你的意思了,上面的答案会起作用,你也可以返回 ajax 操作本身。检查我的帖子的编辑。
    • 这也可以,但让我回到原来的问题——我可以返回一个空函数,但这会破坏将表单处理包装在一个单独的函数中的点,因为我必须配置返回的每次都反对。另一方面,我可以返回配置的函数,但我不希望函数执行,因为它用于表单提交。我可以等到提交表单后再调用该函数,但是我不能事先附加回调。 @Arun 上面的回答做得最好。不过感谢您的反馈!
    【解决方案2】:

    尝试创建自己的延迟

    HandleModalFormSubmit: function (element) {
        var form,
        modalcontainer = $(element).closest('.modal'),
            modal = $(element).closest('.modal-dialog'),
            ajaxdata, $deferred = jQuery.Deferred();
    
    
        if (element.is('form')) form = $(element);
        else {
            form = element.find('form');
        }
    
        $.validator.unobtrusive.parse(form);
    
        $(element).on('submit', function (event) {
            event.preventDefault();
            ajaxdata = $.ajax({
                type: form.method,
                url: form.action,
                data: $(form).serialize()
            }).done(function (data) {
                if (data.status == null) {
                    modal.html(data);
                } else {
                    modalcontainer.modal('hide');
                }
                $deferred.done.apply(this, arguments);
            }).always(function (data) {
                modal.spin(false);
                modal.fadeTo(500, 1);
                $deferred.always.apply(this, arguments);
            }).fail(function () {
                $deferred.fail.apply(this, arguments);
            });
            modal.fadeTo(300, 0);
            modal.spin();
        });
        var returningobject = {
            element: form,
            ajax: ajaxdata
        };
        return $deferred.promise();
    }
    

    【讨论】:

    • 但现在我无法访问 ajax 对象或表单元素(最初返回)..
    • 等我看看你现在在做什么。我可以返回延迟对象而不是我的 ajax 对象
    • 感谢您的回答,我花了 3 个小时才找到您发布的代码有什么问题。你有没有运行过这段代码? $deferred.done.apply(this, arguments) 应替换为 $deferred.done.resolve(this, arguments) 否则根本不会调用 $.when(..).done(..)。检查这个小提琴jsfiddle.net/rLw6y2cw/23
    猜你喜欢
    • 2020-01-04
    • 1970-01-01
    • 2015-11-27
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 2013-11-15
    • 1970-01-01
    相关资源
    最近更新 更多