-
-
Save tbranyen/1235317 to your computer and use it in GitHub Desktop.
/* Pretend app setup stuff is here */ | |
/* Kick off app */ | |
jQuery(function($) { | |
var Gallery = app.module("gallery"); | |
app.Router = Backbone.Router.extend({ | |
initialize: function() { | |
this.gallery = new Gallery.Router("gallery/"); | |
} | |
}); | |
// Actually initialize | |
new app.Router(); | |
}); |
(function(Gallery) { | |
var Helper = app.module("helper"); | |
Gallery.Router = Helper.SubRoute.extend({ | |
routes: { | |
"": "list", | |
"add": "add", | |
"filter": "filter" | |
} | |
}); | |
})(app.module("gallery")); |
(function(Helper) { | |
Helper.SubRoute = Backbone.Router.extend({ | |
constructor: function(prefix) { | |
var routes = {}; | |
// Prefix is optional, set to empty string if not passed | |
prefix = prefix || ""; | |
// Allow for optionally omitting trailing /. Since base routes do not | |
// trigger with a trailing / this is actually kind of important =) | |
if (prefix[prefix.length-1] == "/") { | |
prefix = prefix.slice(0, prefix.length-1); | |
// If a prefix exists, add a trailing / | |
} else if (prefix) { | |
prefix += "/"; | |
} | |
// Every route needs to be prefixed | |
_.each(this.routes, function(callback, path) { | |
if (path) { | |
return routes[prefix + path] = callback; | |
} | |
// If the path is "" just set to prefix, this is to comply | |
// with how Backbone expects base paths to look gallery vs gallery/ | |
routes[prefix] = callback; | |
}); | |
// Must override with prefixed routes | |
this.routes = routes; | |
// Required to have Backbone set up routes | |
Backbone.Router.prototype.constructor.call(this); | |
} | |
}); | |
})(app.module("helper")); |
WAH-WAH. Let us know what you find.
I ended up logging an issue against @geekdave's repo at BackboneSubroute/backbone.subroute#4 - I'm not 100% sure everything is correct (it's a little handwavy, I'm under pressure to get something out the door blahblahblah so I had to move on), but I think that's the gist of things. Hopefully I'll have time to come back to it, if @geekdave isn't able to get to the bottom of it himself.
And how to dynamically remove the subroute?
@SamDecrock you can't without manipulating Backbone.history
and allowing your application to have knowledge of all the paths that were added. This can be quite a complex procedure if you haven't built your application with an ability to get paths from individual subroutes. I tend to create wrapping objects that have an activate and deactivate method that are managed by a facade to a Backbone router.
considering that you have a list of paths (allRoutes
in this example).
for (var path in allRoutes) {
var combinedPath = routerPrefix + '/' + path;
// This removes all trace of the routes from the history
Backbone.history.handlers = _.reject(
Backbone.history.handlers, function(value) {
return String.prototype.search.call(
value.route,
combinedPath
) !== -1;
}
);
}
// Unfortunately, we still have a route in the history for the routerPrefix
// (in fact we should have two, the one used by the primary router and
// one created by the sub router (the latter takes precedence as it has
// been unshifted onto the handlers array. The next step therefore is to
// get all the primary routes registered in the history.
var primaryHandlers = _.filter(Backbone.history.handlers, function(value) {
return String.prototype.search.call(value.route, routerPrefix) !== -1;
});
// If the result has a length greater than 1 (this will be the case most of
// the time) then we need to remove the first one that was registered by
// the subrouter, this leaves the primary route still available to start the
// sub router again when it is needed. Else we want to keep the route as
// it was set by the primary router.
if (primaryHandlers.length > 1) {
Backbone.history.handlers.splice(
Backbone.history.handlers.indexOf(primaryHandlers[0])
, 1);
}
Have you guys tried this out in IE8/9 yet, by any chance? I'm getting a stack overflow, but only IE... trying to track down the recursion now.