Skip to content

Instantly share code, notes, and snippets.

@nagyv
Forked from tbranyen/app.js
Created February 15, 2012 23:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nagyv/1840152 to your computer and use it in GitHub Desktop.
Save nagyv/1840152 to your computer and use it in GitHub Desktop.
backbone.js sub routing
/* Pretend app setup stuff is here */
/* Kick off app */
jQuery(function($) {
var Gallery = app.module("gallery");
app.Router = Backbone.Router.extend({
routes: {
"add": "main_add"
},
initialize: function() {
this.gallery = new Gallery.Router("gallery/");
}
});
// Actually initialize
new app.Router();
});
(function() {
Backbone.Helper = Backbone.Helper || {};
Backbone.Helper.SubRoute = Backbone.Router.extend({
constructor: function(prefix) {
var routes = {};
// Prefix is optional, set to empty string if not passed
this.prefix = prefix = prefix || "";
// Allow for optionally omitting trailing /. Since base routes do not
// trigger with a trailing / this is actually kind of important =)
if (prefix.substr(-1) != "/") {
prefix = prefix + '/';
}
// Every route needs to be prefixed
_.each(this.routes, function(callback, path) {
if (path) {
routes[prefix + path] = callback;
} else {
// 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.substr(0, prefix.length-1)] = callback;
}
});
// Must override with prefixed routes
this.routes = routes;
// Required to have Backbone set up routes
Backbone.Router.prototype.constructor.call(this);
},
navigate: function(route, options) {
if (route.substr(0,1) != '/' && route.indexOf(this.prefix.substr(0,this.prefix.length-1)) != 0) {
route = this.prefix + route;
}
Backbone.Router.prototype.navigate.call(this, route, options);
}
});
})();
@geekdave
Copy link

geekdave commented Apr 4, 2012

Thanks for this! It doesn't seem to work, however, when the initially-loaded URL is a sub-route. The sub-route gets set up correctly, so that the next time the user navigates to a sub-route, it works. But the initial page load only navigates to the main route.

For example, if the first URL loaded is http://example.org/#a/b/c, where the main route handles "a" and the subroute handles "b/c", then on the first page load, only route "a" is triggered. Clicking on "b" after page load works.

Thanks!

@geekdave
Copy link

geekdave commented Apr 4, 2012

Ok, I may have figured it out. I added this code to the end of the constructor() function, right after the call to Router.prototype.

// grab the full URL
var hash = Backbone.history.getHash();

// check if there is already a part of the URL that this subview cares about...
var hashPart = hash.substr(prefix.length, hash.length);

// ...if so, trigger the subroute immediately.  this supports the case where 
// a user directly navigates to a URL with a subroute on the first page load.
if (hashPart && hashPart != "") {
    Backbone.history.loadUrl(prefix + hashPart);
}

With this code, I am able to navigate to http://example.org/#a/b/c, and have the "b" subroute trigger correctly. Please let me know if this sounds like a good approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment