Created
December 13, 2012 17:06
-
-
Save mxriverlynn/4277997 to your computer and use it in GitHub Desktop.
Backbone.ModelRouter - Resolve an :id parameter is a `.modelRoutes` hash, to load a model and then run the callback method with the specified model as the arguments, instead of the id parameter
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
// Backbone.ModelRouter | |
// -------------------- | |
// | |
// v0.0.0 | |
// | |
// Resolve an :id parameter is a `.modelRoutes` hash, to load | |
// a model and then run the callback method with the specified | |
// model as the arguments, instead of the id parameter. | |
// | |
// Copyright (C) 2012 Muted Solutions, LLC. All Rights Reserved. | |
// | |
// Example: | |
// ```js | |
// Backbone.ModelRouter.extend({ | |
// modelRoutes: { | |
// "models/new": "newModel", | |
// "models/:id": "showModel", | |
// "models/:id/action: "modelAction", | |
// "models/:id/subModel/:subId: "subModelAction" | |
// }, | |
// | |
// newModel: function(model){ | |
// model.isNew(); // => true | |
// }, | |
// | |
// showModel: function(model){ | |
// model.id; // => the id from the route... #models/1 | |
// }, | |
// | |
// modelAction: function(model){ | |
// model.id; // => the id from the route... #models/1 | |
// }, | |
// | |
// subModelAction: function(model, subModel){ | |
// model.id; // => the id from the route | |
// subModel.id // => the subId from the route | |
// }, | |
// | |
// // You must provide this method, to create a new | |
// // model instance and set the id (if provided). | |
// getModelTypes: function(){ | |
// // return multiple types for multiple ids, | |
// // based on position in the route definition | |
// return [App.Pools.Pool, App.Liners.Liner]; | |
// // or just return one, for a single id | |
// // return App.Pools.Poo; | |
// } | |
// }); | |
// ``` | |
Backbone.ModelRouter = (function(Backbone, $, _){ | |
"use strict"; | |
var Router = Backbone.Router.extend({ | |
constructor: function(options){ | |
this._setupModelRoutes(); | |
var args = Array.prototype.slice.call(arguments); | |
Backbone.Router.prototype.constructor.apply(this, args); | |
}, | |
// parses the `modelRoutes` and sets up the model fetch | |
// for each route, callign the specified callback method | |
// after the model has been fetched | |
_setupModelRoutes: function(){ | |
var route, routesLength, methodName, resolvedMethodName; | |
var routes = [], | |
modelRoutes = Marionette.getOption(this, "modelRoutes"); | |
// order the routes properly in an array | |
for(route in modelRoutes){ | |
if (modelRoutes.hasOwnProperty(route)){ | |
routes.unshift([route, modelRoutes[route]]); | |
} | |
} | |
// iterate the routes, build the method for the route | |
// and then set up the route for that method | |
routesLength = routes.length; | |
for (var i = 0; i < routesLength; i++){ | |
route = routes[i][0]; | |
methodName = routes[i][1]; | |
resolvedMethodName = "_resolved_" + methodName; | |
if (this.defineRouteMethod){ | |
this.defineRouteMethod(methodName); | |
} | |
this._buildStep(methodName, resolvedMethodName); | |
this._buildRoute(route, methodName, resolvedMethodName); | |
} | |
}, | |
// build the route for the entity loading and callback | |
_buildRoute: function(route, methodName, resolvedMethodName){ | |
var that = this; | |
var method = function(){ | |
var args = Array.prototype.slice.call(arguments); | |
that[resolvedMethodName].apply(that, args); | |
} | |
this.route(route, methodName, method); | |
}, | |
// build the function that loads the entity and then | |
// runs the specified method from the route | |
_buildStep: function(methodName, resolvedMethodName){ | |
var that = this; | |
this[resolvedMethodName] = function(){ | |
var idList = Array.prototype.slice.call(arguments); | |
var length = idList.length; | |
var promises = []; | |
var id; | |
if (length > 0){ | |
for (var i=0; i<length; i++){ | |
id = idList[i]; | |
promises.push(that._loadEntity(id, i)); | |
} | |
} else { | |
promises.push(that._loadEntity()); | |
} | |
$.when.apply($, promises).then(function(){ | |
var args = Array.prototype.slice.call(arguments); | |
that[methodName].apply(that, args); | |
}); | |
}; | |
}, | |
// load the entity and call fetch on it. when it is | |
// done fetching, resolve the promise so that the | |
// router methods can be called | |
_loadEntity: function(id, index){ | |
var self = this; | |
var promise = $.Deferred(); | |
// get the model types to load, based on index | |
var ModelTypes = this.getModelTypes(); | |
var ModelType; | |
if (_.isArray(ModelTypes)){ | |
ModelType = ModelTypes[index]; | |
} else { | |
ModelType = ModelTypes; | |
} | |
// set up the model with the specified id | |
var model = new ModelType({id: id}); | |
// if we had an id parameter, load up the | |
// model for that id, and then resolve the promise. | |
// otherwise, just resolve the promise and move on | |
if (!model.isNew()){ | |
model.fetch({ | |
success: function(){ | |
promise.resolve(model); | |
} | |
}); | |
} else { | |
promise.resolve(model); | |
} | |
return promise.promise(); | |
} | |
}); | |
return Router; | |
})(Backbone, jQuery, _); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment