Skip to content

Instantly share code, notes, and snippets.

@kmiyashiro
Created April 7, 2012 22:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmiyashiro/2332537 to your computer and use it in GitHub Desktop.
Save kmiyashiro/2332537 to your computer and use it in GitHub Desktop.
Backbone wrapper
// Wrapper to include all the plugins we use.
define(function(require) {
var Backbone = require('use!libs/backbone/backbone');
require('view/CleanView');
return Backbone;
});
/**
* Extend Backbone.View to have a "close" function.
* Unbind all triggers and events.
* Save an array of all bound events to unbind
* Define onClose on views to clean up model/collection listeners
*/
define(function(require) {
var Backbone = require('use!libs/backbone/backbone'),
_ = require('use!underscore');
// CleanView adds some auto-cleanup of Events
// Must pass Parent view in init options to register self.
Backbone.CleanView = Backbone.View.extend({
constructor: function(opts) {
// Hold all child views
this.childViews = [];
// Automatically add self to parent childViews
if (opts && opts.parentView) {
this.parentView = opts.parentView;
this.parentView.childViews.push(this);
}
Backbone.View.prototype.constructor.apply(this, arguments);
},
// Basically just sets the parentView so you don't have to do it
addView: function(View, opts, classOpts) {
// Fill in parentView if it isn't set
opts = _.defaults({}, opts, { parentView: this });
return new View(opts, classOpts);
},
// bindTo facilitates the binding and unbinding of events
// from objects that extend `Backbone.Events`. It makes
// unbinding events, even with anonymous callback functions,
// easy.
//
// Thanks to Johnny Oshika for this code.
// http://stackoverflow.com/questions/7567404/backbone-js-repopulate-or-recreate-the-view/7607853#7607853
// Store the event binding in array so it can be unbound
// easily, at a later point in time.
bindTo: function(obj, eventName, callback, context) {
context = context || this;
obj.on(eventName, callback, context);
if (!this.bindings) this.bindings = [];
this.bindings.push({
obj: obj,
eventName: eventName,
callback: callback,
context: context
});
},
// Unbind all of the events that we have stored.
unbindAll: function () {
_.each(this.bindings, function(binding) {
binding.obj.off(binding.eventName, binding.callback);
});
this.bindings = [];
},
// Unbinds all listeners created by view and recursively removes any
// childViews and their listeners.
// Does not remove element, just clears it by default. Pass
// { remove: true } to remove the element.
close: function(opts) {
// Unbind all bindings this view created on other objects
this.unbindAll();
// Unbind all bindings to this view
this.off();
this.unbind();
this.undelegateEvents();
// Remove view from DOM
if (opts && opts.remove) {
this.remove();
} else {
this.$el.empty();
}
if (this.onClose) {
this.onClose();
}
// Recursively clean up any child views
if (this.childViews) {
_.each(this.childViews, function(view) {
view.close({ remove: true });
});
}
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment