11

Backbone.Marionetteを使用してItemViewをレンダリングおよび閉じるときにアニメーションを設定しようとしています。ビューをレンダリングする場合、これはかなり簡単です。

MyItemView = Backbone.Marionette.View.extend({
   ...
   onRender: function() {
     this.$el.hide().fadeIn();
   }
   ...
});

これにより、レンダリング時にビューがフェードインします。しかし、閉じたときにビューをフェードアウトしたいとします。

beforeClose: function() {
   this.$el.fadeOut();       // doesn't do anything....
}

アイテムは呼び出した直後に閉じるため、this.beforeClose()これは機能しません。そのため、アニメーションを完了する時間がありません。

マリオネットをそのまま使用して、クロージングアニメーションを完成させる方法はありますか?


または、これは私が使用している回避策です。

_.extend(Backbone.Marionette.ItemView.prototype, {
    close: function(callback) {

        if (this.beforeClose) {

            // if beforeClose returns false, wait for beforeClose to resolve before closing
            // Before close calls `run` parameter to continue with closing element
            var dfd = $.Deferred(), run = dfd.resolve, self = this;
            if(this.beforeClose(run) === false) {
                dfd.done(function() {
                    self._closeView();              // call _closeView, making sure our context is still `this`
                });
                return true;
            }
        }

        // Run close immediately if beforeClose does not return false
        this._closeView();
    },

// The standard ItemView.close method.
    _closeView: function() {
        this.remove();

        if (this.onClose) { this.onClose(); }
        this.trigger('close');
        this.unbindAll();
        this.unbind();      
    }
});

今、私はこれを行うことができます:

beforeClose: function(run) {
    this.$el.fadeOut(run);      // continue closing view after fadeOut is complete
    return false;
},

私はMarionetteを初めて使用するので、これが最善の解決策かどうかはわかりません。これが最善の方法である場合は、プルリクエストを送信しますが、これが他のタイプのビューでどのように機能するかについてもう少し考えたいと思います。

これは、クローズ時に確認を求める(この問題を参照)、またはあらゆる種類の非同期要求を実行するなど、他の目的に使用される可能性があります。

考え?

4

1 に答える 1

18

メソッドをオーバーライドすることはこれを行う1つの方法ですが、複製する代わりにcloseMarionettesメソッドを呼び出すことができるため、少し短く書くことができます。close

_.extend(Backbone.Marionette.ItemView.prototype, {
    close: function(callback) {
        var close = Backbone.Marionette.Region.prototype.close;
        if (this.beforeClose) {

            // if beforeClose returns false, wait for beforeClose to resolve before closing
            // Before close calls `run` parameter to continue with closing element
            var dfd = $.Deferred(), run = dfd.resolve, self = this;
            if(this.beforeClose(run) === false) {
                dfd.done(function() {
                    close.call(self);
                });
                return true;
            }
        }

        // Run close immediately if beforeClose does not return false
        close.call(this);
    },


});

もう1つのアイデアは、removeビューの方法を上書きすることです。したがって、ビューの要素をフェードアウトしてから、DOMから削除します

remove: function(){
  this.$el.fadeOut(function(){
    $(this).remove();
  }); 
}
于 2012-09-16T19:18:02.820 に答える