Skip to content

Instantly share code, notes, and snippets.

@chrisvariety
Created August 10, 2012 14:02
Show Gist options
  • Save chrisvariety/3314417 to your computer and use it in GitHub Desktop.
Save chrisvariety/3314417 to your computer and use it in GitHub Desktop.
bad backbone
// Templating
// Adds the method "twirl" to every view to render its mustache template into itself
// Assumes views are keeping templates in: options.templates.tmpl_name
// twirl() -> renders options.template
// twirl(tmpl_name) -> renders options.templates.tmpl_name
_.extend(Backbone.View.prototype, {
twirl: function(tmpl_name) {
var tmpl = (tmpl_name) ? this.options.templates[tmpl_name] : this.options.template;
var tmpl_object = this.model || this.collection;
if (tmpl && tmpl_object) {
$(this.el).html(Mustache.to_html(tmpl, tmpl_object, window.atk.page.partials));
return true;
} else {
throw("Could not render template " + tmpl_name + " for view.")
return false;
}
}
});
_.extend(Backbone.Model.prototype, {
// This system moves relations from the attributes hash into a concrete property on the Model
// If the relation in the attributes is already a Backbone Model, then it is just moved.
// If it is a value object (ie from a JSON response), then it is converted into a Model or Collection.
// If there is no data for this object, then no object is created
// Associations "in_rails_syntax" are renamed "inJavaScriptSyntax"
createAssociation: function(key, assoc, belongsTo) {
var rel_name = underToCamel(key);
var rel_data = this.get(key);
if (rel_data instanceof assoc) {
this[rel_name] = this.get(key);
} else {
this[rel_name] = new assoc(rel_data);
}
delete this.attributes[key];
// Establish reciprocal rel if desired
if (belongsTo) {
this[rel_name][belongsTo] = this;
}
},
makeMany: function(assocs, belongsTo) {
_.each(assocs, function(assoc, key, assocs) {
this.createAssociation(key, assocs[key]['collection'], assocs[key]['belongsTo']);
}, this);
},
makeOne: function(assocs) {
_.each(assocs, function(assoc, key, assocs) {
this.createAssociation(key, assocs[key]['model'], assocs[key]['belongsTo']);
}, this);
},
// Create default getter functions for all desired attributes
// These are mainly used by mustache, which cannot call 'get'
// Getters are renamed in js syntax, so 'get image_asset_url' = 'getImageAssetUrl' ok?
createGetters: function() {
var model = this;
var getterList = arguments;
var getterFunctions = {};
_.each(getterList, function(getter) {
getterFuncName = underToCamel(getter);
getterFuncName = 'get' + upCaseFirstChar(getterFuncName);
if (!model[getterFuncName]) {
getterFunctions[getterFuncName] = function() { return this.get(getter); }
}
});
_.extend(this, getterFunctions);
},
// Force a model to require an attribute
requires: function() {
var model = this;
var reqList = arguments;
_.each(reqList, function(req) {
if (typeof model.get(req) == "undefined") {
throw("Invalid model");
}
});
},
// The url function doesn't work QUITE right with our nested resources,
// so let's kick it in the nuts so it respects Model.urlRoot as a function
url: function() {
var base;
if (this.urlRoot) {
// use our urlRoot function or property
base = _.isFunction(this.urlRoot) ? this.urlRoot() : this.urlRoot;
} else if (this.collection && this.collection.url) {
// then look to the collection's url
base = _.isFunction(this.collection.url) ? this.collection.url() : this.collection.url;
} else {
throw new Error("A 'url' property or function must be specified");
return; // fail
}
if (this.isNew()) {
return base;
} else {
// return base url plus model id
return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + this.id;
}
},
// Wouldn't it be nice to be able to traverse models in a collection with next and prev?
next: function() {
if (!this.collection) return null;
var i = this.collection.indexOf(this);
var nextModel = this.collection.at(i+1);
return nextModel ? nextModel : null;
},
prev: function() {
if (!this.collection) return null;
var i = this.collection.indexOf(this);
var nextModel = this.collection.at(i-1);
return nextModel ? nextModel : null;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment