-
-
Save nagyv/1840152 to your computer and use it in GitHub Desktop.
backbone.js sub routing
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
/* 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(); | |
}); |
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
(function(Gallery) { | |
var Helper = app.module("helper"); | |
Gallery.Router = Helper.SubRoute.extend({ | |
routes: { | |
"": "list", | |
"add": "add", | |
"filter": "filter" | |
}, | |
list: function() { | |
this.navigate('add'); // -> redirects to app.Router.gallery.add | |
this.navigate('/add'); // -> redirects to app.Router.main_add | |
} | |
}); | |
})(app.module("gallery")); |
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
(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); | |
} | |
}); | |
})(); |
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
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!