2

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

より具体的に言うと、私のプラグインは、ドラッグおよびドロップ可能な jQuery UI を使用しています。droppable dropで、 updateというオプションで定義された関数を呼び出します。AJAX 呼び出しであるupdateが呼び出された後、クリーンアップを実行したいと考えています。プラグインのユーザーがこのクリーンアップ コールを実行する必要はありません。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!');
            });
}

dropコールバックへの約束として AJAX 呼び出しを返しています。ドロップ コールバック内では、クリーンアップ操作removeSelectedItemsを常に実行したいので、.then() 関数を使用します。実行されていないようです。

このパターンは良いアイデアのように聞こえますか。このデザインを手伝ってくれる人はいますか?ドロップコールバック内で完了関数が実行されないのはなぜですか?

4

1 に答える 1

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();
            });
        }
    });

アップデート:

開発者が update 関数を指定するため、開発者が遅延オブジェクトを適切に返さない可能性が常にあります。それを確認し、その場合は例外をスローする必要があります。

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.");
            }
        }
    });
于 2012-01-12T20:43:50.997 に答える