Reputation: 1410
I am using Backbone's "all" event to catch all route events in my app in order to log the page views. This works well as long as I don't use navigate
to manually trigger a route.
In the following example, I forward the user from the dashboard
route to the login
route. Backbone fires the event AFTER the route callback is executed, leading to the following output:
showDashboard
showLogin
route:showLogin
tracking:/login
route:showDashboard
tracking:/login
Obviously this is not what I want. I know I could call showLogin
instead of using navigate
to trigger the login route and this is what I am doing right now, but I would like to know why the order of the events is not the same than the order of the triggered callbacks.
Here is my router (shortened):
var AppRouter = Backbone.Router.extend({
routes: {
"/login": "showLogin",
"": "showDashboard",
},
initialize: function() {
return this.on('all', this.trackPageview);
},
trackPageview: function(eventName) {
console.log(eventName);
var url = Backbone.history.getFragment();
console.log('tracking: ' + url);
},
showDashboard: function() {
console.log('showDashboard');
// check if the user is logged in etc.
this.navigate('#/login', { trigger: true });
},
showLogin: function() {
console.log('showLogin');
}
});
Upvotes: 0
Views: 1476
Reputation: 30442
Backbone's Router
is actually very simple, and if you read the code you'll see the following in it's constructor:
this._bindRoutes();
this.initialize.apply(this, arguments);
_bindRoutes
attaches all your routes as you expect, and it does this before your initialize
function gets called. So your binding will always fire after Backbone's does.
You're probably going to be better off finding another way to do this.
You could call a before
type function yourself in your routes to do stuff like track pageviews/etc. Or maybe you could just override route
, track your pageview and then make sure to call Backbone's implementation with something like Backbone.Router.prototype.route.call(arguments);
Upvotes: 1