我正在编写一个 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/