Created
August 10, 2012 14:02
-
-
Save chrisvariety/3314417 to your computer and use it in GitHub Desktop.
bad backbone
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_.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