Created
May 11, 2012 05:58
-
-
Save dgs700/2657819 to your computer and use it in GitHub Desktop.
Remove all hardcoded dependancies from your Backbone classes for clean MVC separation!
This file contains hidden or 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
/* Copywrite 2012, David Shapiro - portions added to existing Backbone code*/ | |
/* Subject to FFRUYL licensing - Feel free to rip and use as you like. */ | |
/*globals Backbone:true, _:true, $:true*/ | |
// @name: Configurator | |
// | |
// @tagline: Configurator for Backbone Apps- models, views and routers | |
// | |
// @description: | |
// Experimental code | |
// -Maintain Backbone MVC classes free of hardcoded dependancies including strings, css, text, and html fragments. | |
// -Create and modify application configuration object and inject into app bootstrap. | |
// -Modify configurations and trigger config:changed events during runtime to dynamically decorate your app. | |
// -Configurator classes and config objects can be subclassed or mixed into to | |
// Class and inheritance structure follows the same conventions used in core Backbone modules | |
Backbone.Configurator = (function (Backbone, _, $) { | |
"use strict"; | |
var Configurator = {}, config; | |
Configurator.version = "0.01"; | |
//The general idea is to remove any and all hardcoded dependancies from your | |
//Backbone classes and list them here or add by subclassing, mixing in, or dynamically at runtime | |
//changes to this object can trigger config change events that your application can react to | |
//sample, skeletal configuration for basic Backbone modules | |
//you can extend this object or set your own via | |
// Backbone.Configurator.config = {your base config} prior to extending your own | |
//Configurator classes | |
config = { | |
// | |
app: { | |
//name of the data collection to look for on page load | |
//bootStrapData: My.JSON.dataObject, | |
//any jQuery selector strings needed to reference layout containters | |
selectors: { | |
domAttachClass: '.some_content_div', | |
rootPageElem: 'body' | |
}, | |
//switches to indicate if the app contains any optional views | |
//to include in initialization | |
pager:false, | |
filter:false, | |
//optional classnames to for views (controllers) to reference | |
classes: { | |
//model: My.Application.ItemClassName, | |
//collection: My.Application.CollectionClassName | |
} | |
}, | |
router: { | |
routes:{ | |
'': 'home' | |
}, | |
//reverse hash of routes for use with router.navigate() | |
paths:{ | |
home: '' | |
} | |
}, | |
history: { | |
root: '/', | |
pushState: true | |
}, | |
item: { | |
urlRoot: '/my_collection/' | |
}, | |
collection: { | |
url: '/my_collection/' | |
//item: My.Collections.ItemClassName | |
}, | |
test: { | |
foo:'bar' | |
} | |
}; | |
Configurator = function(props, options) { | |
this.config = $.extend(true,{}, this.constructor.config); | |
this.add(props || {}); | |
this._configure(options || {}); | |
this.initialize.apply(this, arguments); | |
}; | |
Configurator.config = config; | |
// List of config instance options to be merged as properties. Empty by default. | |
// Add any special instance options you want set directly on the config instance. | |
var configOptions = []; | |
// Set up all inheritable **Backbone.Configurator** properties and methods. | |
_.extend(Configurator.prototype, Backbone.Events, { | |
// recursively add properties to the config object | |
// triggers a change:config event unless {silent:true} | |
add: function(props){ | |
if(typeof props == 'object'){ | |
$.extend(true, this.config, props); | |
if(!arguments[1]){ | |
this.trigger('change:config', props); | |
} | |
} | |
}, | |
// Same functionality as Bacbone.View. To use, add values to the | |
// configOptions array. | |
_configure: function(options) { | |
if (this.options) | |
options = _.extend({}, this.options, options); | |
for (var i = 0, l = configOptions.length; i < l; i++) { | |
var attr = configOptions[i]; | |
if (options[attr]) | |
this[attr] = options[attr]; | |
} | |
this.options = options; | |
}, | |
// Initialize is an empty function by default. Override it with your own | |
// initialization logic. | |
initialize: function(){}, | |
//warning... this will replace the current config obj. | |
//triggers a reset event unless silent:true | |
resetConfig: function(conf){ | |
conf = conf || {}; | |
this.config = conf; | |
if(!arguments[1]){ | |
this.trigger('reset:config', conf); | |
} | |
}, | |
getConfig: function(){ | |
return this.config; | |
} | |
}); | |
// The self-propagating extend function that Backbone classes use. | |
// Added configProps to for deep copying | |
Configurator.extend = function(configProps, protoProps, classProps) { | |
var child = inherits(this, configProps, protoProps, classProps); | |
child.extend = this.extend; | |
return child; | |
}; | |
// Shared empty constructor function to aid in prototype-chain creation. | |
var ctor = function(){}; | |
// Helper function to correctly set up the prototype chain, for subclasses. | |
// Similar to `goog.inherits`, but uses a hash of prototype properties and | |
// class properties to be extended. | |
var inherits = function(parent, configProps, protoProps, staticProps) { | |
var child; | |
// The constructor function for the new subclass is either defined by you | |
// (the "constructor" property in your `extend` definition), or defaulted | |
// by us to simply call the parent's constructor. | |
if (protoProps && protoProps.hasOwnProperty('constructor')) { | |
child = protoProps.constructor; | |
} else { | |
child = function(){ | |
parent.apply(this, arguments); | |
}; | |
} | |
// Inherit class (static) properties from parent. | |
_.extend(child, parent); | |
// reset child.config to a deep copy since we want to remove any references | |
// to parent.config before adding or changing config props | |
child.config = $.extend(true, {}, parent.config); | |
// Set the prototype chain to inherit from `parent`, without calling | |
// `parent`'s constructor function. | |
ctor.prototype = parent.prototype; | |
child.prototype = new ctor(); | |
// Add deep copy of config properties (instance properties) to the subclass, | |
// if supplied since we don't want to copy any nested references. | |
if (configProps) $.extend(true, child.config, configProps); | |
// Add prototype properties (instance properties) to the subclass, | |
// if supplied. | |
if (protoProps) _.extend(child.prototype, protoProps); | |
// Add static properties to the constructor function, if supplied. | |
if (staticProps) _.extend(child, staticProps); | |
// Correctly set child's `prototype.constructor`. | |
child.prototype.constructor = child; | |
// Set a convenience property in case the parent's prototype is needed later. | |
child.__super__ = parent.prototype; | |
return child; | |
}; | |
return Configurator; | |
}(Backbone, _, $)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment