jquery - 使用 jQuery Deferred 插件内部始终调用清理方法

标签 jquery jquery-deferred

我正在编写一个 jQuery UI 插件。在该插件内,当发生操作时,我将调用插件选项之一作为回调。一旦回调完成,我想运行一些清理代码。

更具体地说,我的插件使用 jQuery UI 可拖放。在可删除的 drop 上,我调用选项中定义的名为 update 的函数。调用 update 后(这是一个 AJAX 调用),我想执行一些清理操作。我不希望插件的用户被要求执行此清理调用;我希望在更新 AJAX 方法成功后自动进行清理调用。

我认为在这里使用 jQuery 的 Deferred 是有意义的。以下是插件 drop 实现的一些代码:

self.connectedLists = $(self.options.connectWith)
    .not(self.list)
    .droppable({
        hoverClass: 'ui-selectablelist-active',
        drop: function(e, ui) {
            var sender = $(ui.draggable).closest('ul'),
                deferred = self.options.update.call(self, e, {
                    sender: sender,
                    receiver: $(this),
                    items: selectedItems
                });

            deferred.then(function () {
                self.removeSelectedItems();
            });
        }
    });

插件实现者的代码如下所示:

update: function (e, ui) {
    var self = this;
    return $.post(url, 
            {                 
                // some data                         
            })
            .done(function (data) {
                console.log('updated!');
            });
}

我将返回 AJAX 调用作为对 drop 回调的 promise 。在 drop 回调中,我想始终执行清理操作 removeSelectedItems,因此我使用 .then() 函数。它似乎没有运行。

这种模式听起来是个好主意吗?谁能帮我做这个设计吗?为什么我的完成函数没有在 drop 回调中运行?

最佳答案

不要使用.then,而是使用.always

.then 用于向延迟对象添加回调:

deferred.then(donecallbacks,failcallbacks)

尝试:

self.connectedLists = $(self.options.connectWith)
    .not(self.list)
    .droppable({
        hoverClass: 'ui-selectablelist-active',
        drop: function(e, ui) {
            var sender = $(ui.draggable).closest('ul'),
                deferred = self.options.update.call(self, e, {
                    sender: sender,
                    receiver: $(this),
                    items: selectedItems
                });

            deferred.always(function () {
                self.removeSelectedItems();
            });
        }
    });

更新:

由于开发人员将指定更新函数,因此开发人员始终有可能无法正确地将延迟对象返回给您。您应该检查这一点并在这种情况下抛出异常。

self.connectedLists = $(self.options.connectWith)
    .not(self.list)
    .droppable({
        hoverClass: 'ui-selectablelist-active',
        drop: function(e, ui) {
            var sender = $(ui.draggable).closest('ul'),
                deferred = self.options.update.call(self, e, {
                    sender: sender,
                    receiver: $(this),
                    items: selectedItems
                });
            if (deferred.always) {
                deferred.always(function () {
                  self.removeSelectedItems();
                });
            }
            else {
                $.error("Update must return a deferred object.");
            }
        }
    });

关于jquery - 使用 jQuery Deferred 插件内部始终调用清理方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8841491/

相关文章:

jquery - event.preventDefault() 在 Chrome 和 Opera 中不起作用

javascript - React 组件中的 $(this)

jquery点击更改类

jquery - 延迟和 Ajax

javascript - jQuery promise 一切

javascript - 使用 javascript(或 jQuery)选择和操作 CSS 伪元素,例如::before 和::after

javascript - IF 是 JavaScript 中的函数吗?

jQuery.Deferred()/GWT 中的 Promises 功能?

jquery - 将 Backbone Js 与 jQuery Deferred 结合使用

javascript - 混合回调函数和 jQuery 延迟队列