Skip to content

Instantly share code, notes, and snippets.

@fearphage
Created December 7, 2012 22:55
Show Gist options
  • Save fearphage/4237211 to your computer and use it in GitHub Desktop.
Save fearphage/4237211 to your computer and use it in GitHub Desktop.
Make Backbone Your Own.
define(function () {
"use strict";
var templates = {};
return Backbone.View.extend({
template: '<div></div>',
_templatize: function () {
if ( !templates[ this.template ] ) {
templates[ this.template ] = _.template( this.template );
}
return templates[ this.template ];
},
prerender: function () {},
__render: function () {
this.$el.html( this._templatize()( this.serialize() ) );
this._setupElements();
},
render: function () {
this.prerender();
this.__render();
this.postrender();
return this;
},
postrender: function () {},
__bufferedSerialize: null,
serialize: function () {
if ( this.__bufferedSeralize && !_.isEmpty( this.__bufferedSerialize )) {
return this.__bufferedSerialize;
}
var toSerialize = {};
if ( this.collection || this.model ) {
toSerialize = ( this.collection || this.model );
this.bind( toSerialize, 'all', function () {
this.__bufferedSerialize = null;
});
this.__bufferedSerialize = toSerialize = toSerialize.toJSON();
}
return toSerialize;
},
// Notable elements - Do override
elements: [],
_setupElements: function () {
if ( !this.elements.length ) { return this; }
this.elements.forEach(function ( el ) {
this[ '$' + el ] = this.$el.find('[data-el=' + el + ']');
}, this);
return this;
},
__bound: [],
bind: function ( obj, event, fn ) {
this.__bound.push( obj );
obj.on( event, fn, this );
return {
unbind: function () {
obj.off( null, null, this );
}.bind( this )
};
},
_unbind: function () {
this.__bound.forEach(function ( obj ) {
obj.off( null, null, this );
}, this);
return this;
},
predestroy: function () {},
postdestroy: function () {},
__destroy: function () {
this._unbind();
this.trigger( 'destroy', this );
},
destroy: function () {
this.predestroy();
this.__destroy();
this.remove();
this.postdestroy();
return this;
},
animDestroy: function ( speed, method, fn ) {
this.predestroy();
this.$el[ method || 'fadeOut' ]( speed || 350, function () {
this.__destroy();
this.remove();
this.postdestroy();
}.bind( this ));
}
});
});
define([
'views/base.view'
],
function ( BaseView ) {
"use strict";
return BaseView.extend({
Child: Backbone.View,
initialize: function () {
this.children = [];
if ( this.options.children ) {
this.options.children.forEach(function ( child ) {
this.push( child );
}, this );
}
},
render: function ( method ) {
this.prerender();
BaseView.prototype.__render.apply( this, arguments );
this.collection.each(function ( model ) {
var view = new this.Child({ model: model });
this.addChild( view );
}, this);
this.postrender();
return this;
},
push: function ( view, index ) {
if ( !!!~this.children.indexOf( view ) ) {
index = typeof index === 'number' ? index : this.children.length;
this.children.push( view );
this.bind( view, 'destroy', function () {
this.children.splice( index, 1 );
});
}
return this;
},
addChild: function ( view, method ) {
if ( view instanceof Backbone.Model ) {
view = new this.Child({ model: view });
}
this.push( view );
this.$el[ method || 'append' ]( view.render().el );
return this;
},
destroy: function () {
this.predestroy();
this.children.forEach(function ( view ) {
view.destroy();
});
BaseView.prototype.__destroy.apply( this, arguments );
this.remove();
this.postdestroy();
return this;
}
});
});
define([
'views/base.view',
'text!tmpl/tweet.html'
],
function ( BaseView, tmpl ) {
"use strict";
return BaseView.extend({
tagName: 'li',
template: tmpl,
events: {
'click': function ( e ) {
e.preventDefault();
this.destroy();
}
}
});
});
define([
'views/list.view',
'views/tweet.view'
],
function ( ListView, TweetView ) {
"use strict";
return ListView.extend({
tagName: 'ul',
Child: TweetView,
initialize: function () {
ListView.prototype.initialize.apply( this, arguments );
var unbind = this.bind( this.collection, 'reset', function ( collection ) {
this.render();
unbind.unbind();
});
this.bind( this.collection, 'add', function ( tweet ) {
this.addChild( tweet, 'prepend' );
});
this.collection.fetch();
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment