Skip to content

Instantly share code, notes, and snippets.

@guilherme
Last active December 17, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guilherme/5621624 to your computer and use it in GitHub Desktop.
Save guilherme/5621624 to your computer and use it in GitHub Desktop.
// Example usage:
// MyCompositeView = Backbone.Marionette.CompositeView.extend({
// template: '#template',
// itemView: Namespace.InterchangeableView,
// itemViewOptions: function(model, index) {
// return { showView: myShowView,
// editView: myEditView,
// model: model
// };
// },
// itemViewContainer: '#container'
// });
Namespace.InterchangeableView = (function(Backbone, _) {
var InterchangeableView = function(options) {
var options = options || {};
var showView = options.showView; delete options.showView;
var editView = options.editView; delete options.editView;
if(!showView) {
throw new Error("You must specify a showView");
};
if(!editView) {
throw new Error("You must specify a editView");
};
this.options = options;
this.cid = _.uniqueId('view');
this.showView = showView;
this.editView = editView;
this._currentView = new this.showView(this.options);
this.delegateEvents();
return this;
};
_.extend(InterchangeableView.prototype, Backbone.Events, {
render: function() {
this._currentView.render();
this.el = this._currentView.el;
this.$el = this._currentView.$el;
return this;
},
close: function() {
if(this._currentView) {
this._currentView.close();
this.$el = this.el = undefined;
};
return this;
},
swapView: function(view, model) {
if(this._currentView) {
// clean the event bindings from old view
this._currentView.unbindUIElements();
this._currentView.stopListening();
this._currentView.undelegateEvents();
// clean the ui element
this._currentView.$el.empty();
// clean the swap events
this.undelegateEvents();
// build a new view
var newView = new view(_.extend(this.options, { model: model || this.options.model }));
// set the old element on the new view
newView.setElement(this._currentView.$el);
// delete the old view
delete this._currentView;
// set up the new view as the current
this._currentView = newView;
// delegate events
this.delegateEvents();
// render the new view
this.render();
};
},
undelegateEvents: function() {
var _this = this;
if(this._currentView) {
_this._currentView.off('model:edit');
_this._currentView.off('model:show');
};
},
delegateEvents: function() {
var _this = this;
this._currentView.on('model:edit', function(model) { _this.swapView(_this.editView, model); });
this._currentView.on('model:show', function(model) { _this.swapView(_this.showView, model); })
},
});
return InterchangeableView;
})(Backbone, _);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment