Reputation: 561
I'm working with a Backbone project, and in our router we specify a default route at the end of the routes
property:
routes: {
"things": "stuff",
"*actions": "default"
}
From a bit of searching around, I've seen a couple of places, such as this StackOverflow answer and the Backbone tutorial, which suggest adding a default route this way.
However, this deeply concerns me, because from what I can see in the Backbone source, the routes
property is simply iterated over to add all the routes in it, and to the best of my knowledge, object iteration in JavaScript doesn't guarantee any ordering. Therefore, with the above routes
definition, it's not guaranteed that the default route has lowest precedence just by virtue of being at the end of the definition.
Is the behavior essentially undefined here, and things are actually working out just a matter of pure luck, or is there something else going on that actually makes this a safe thing to do?
Upvotes: 3
Views: 159
Reputation: 35790
As you identified, routes derived from the route
property have no guaranteed order ... although in practice many browsers will iterate through them in the order defined, and you could also guarantee the order by using the route method instead.
But what about those two examples you linked? Well, if you look carefully at them, you'll notice they don't have any other routes at the same level the way you do. The splat syntax exists simply to a provide more readable way of writing "anything that's not a question mark" (ie. ([^?]*?)
); it's not actually meant to be a default handler.
So, if what you're trying to achieve is:
if (url == 'things') {
doStuff();
} else {
doActions();
}
you have two choices. If you're willing to change your url structure you can simply have:
/things
/actions/*actions
If you're not, you just need to define a route that differentiates:
routes: {':rootLevelPath': rootLevelPathRoute},
rootLevelPathRoute: function(rootLevelPath) {
if (rootLevelPath == 'things') {
doThings();
} else {
doActions();
}
}
Upvotes: 1