2012-09-16 19 views
10

Backbone.MarionetteでレンダリングしてItemViewを閉じるときにアニメーションを設定しようとしています。ビューをレンダリングする場合、これはかなりシンプルです。Backbone.Marionette:beforeまで閉じるビューを閉じる閉じるアニメーションが完了しました

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; 
}, 

を私はマリオネットを使用する新しいので、私これが最善の解決策であるかどうかはわかりません。これが最善の方法であれば、私はプルリクエストを提出しますが、他のタイプのビューとどのように機能するかをもう少し考えてみたいと思います。

これは、クローズ時の確認(issue参照)や、あらゆる種類の非同期要求の実行など、他の目的にも使用できます。

思考?

答えて

18

closeメソッドをオーバーライドすると、これを行うための一つの方法ですが、代わりにそれを複製するのマリオネット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); 
    }, 


}); 

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

remove: function(){ 
    this.$el.fadeOut(function(){ 
    $(this).remove(); 
    }); 
} 
+0

Ah ...ありがとう!私は単純な方法が必要であることを知っていて、View.removeを上書きすることは私にとっては簡単なようです。ところで、fadeOutコールバックでは、 '$(this).remove()'または 'Backbone.Marionette.ItemView.prototype.call(self)'を呼び出す必要があります – eschwartz

+0

remove関数をオーバーライドする方がより良い解決策ですcloseメソッドをオーバーライドします。それは私にとって素晴らしい仕事でした。ありがとう。 – earl3s

関連する問題