2012-01-12 70 views
2

我在寫一個jQuery UI插件。在那個插件裏面,當一個動作發生時,我將調用其中一個插件選項作爲回調。一旦這個回調完成,我想運行一些清理代碼。使用jQuery延期插件總是調用清理方法

更具體地說,我的插件使用jQuery UI可拖放和可拖放。在droppble 下降,我調用更新選項中定義的函數。在更新被調用,這是一個AJAX調用,我想執行一些清理。我不希望插件的用戶需要執行此清理調用;我希望更新AJAX方法成功後自動發生清理調用。

我想在這裏使用jQuery的Deferred有意義。下面是該插件的下降執行一些代碼:

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 drop內部,我想執行清理操作removeSelectedItems總是,所以我使用.then()函數。它似乎沒有運行。

這種模式聽起來像一個好主意。任何人都可以用這個設計來幫助我?爲什麼我的完成函數在下拉回調中運行?

回答

2

而不是使用.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."); 
      } 
     } 
    }); 
+0

Ya。我添加如果(!延遲)拋出'更新選項方法必須返回一個Promise對象';在我的第一篇文章後。偉大的思想...... – 2012-01-12 22:02:44

+0

然後調用實際上工作,但我同意它總是使用更合適。 – 2012-01-13 17:32:04