2012-01-12 6 views
2

jQuery UIプラグインを作成しています。そのプラグインの中で、アクションが発生すると、プラグインオプションの1つをコールバックとして呼び出しています。コールバックが完了したら、クリーンアップコードを実行したい。jQuery Deferred insideプラグインを使用して、常にクリーンアップメソッドを呼び出します。

具体的には、私のプラグインはjQuery UIをドラッグアンドドロップ可能に使います。ドロップ可能なのドロップがの場合、の更新というオプションで定義された関数を呼び出します。 更新が呼び出された後(AJAX呼び出し)、私はいくつかのクリーンアップを実行したいと思います。私はこのクリーンアップコールを実行するためにプラグインのユーザに要求されません。 AJAXメソッドの更新が成功した後でクリーンアップコールが自動的に発生するようにしたい。

ここでjQueryのDeferred made senseと思っていました。ここでは、プラグインのドロップ実装のためのいくつかのコードです:

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呼び出しを返しますよコールバック。ドロップコールバックの中で、私はクリーンアップ操作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

aa。私は追加しましたif(!deferred)throw '更新オプションメソッドはPromiseオブジェクトを返さなければなりません';私の最初の投稿後。偉大な心... –

+0

その後、実際に呼び出されたコールが、私はそれが常に使用するより適切だと同意します。 –