我试图设置动画渲染和关闭一个ItemView与Backbone.Marionette.为了呈现视图,这是相当简单的:
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,所以我不知道这是否是最好的解决方案.如果这是最好的方法,我会提交一个拉动请求,尽管我想更多地考虑如何使用其他类型的视图.
这可能会用于其他目的,例如要求关闭确认(请参阅此issue)或运行任何类型的异步请求.
思考?
解决方法
覆盖close方法是一种方法,但是您可以将其缩短一点,因为您可以调用Marionette close方法而不是复制它:
_.extend(Backbone.Marionette.ItemView.prototype,{ close: function(callback) { var close = Backbone.Marionette.Region.prototype.close; if (this.beforeClose) { // if beforeClose returns false,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); },});
另一个想法是覆盖您的视图的删除方法.所以你淡出视图的元素,然后从DOM中删除它
remove: function(){ this.$el.fadeOut(function(){ $(this).remove(); }); }