Redirect route to another

I am trying to redirect a route to another until a route callback is made. I have the following code:

console.log("file loaded"); (function (History) { var _navigate = History.prototype.navigate; _.extend(History.prototype, { navigate: function (fragment, opts) { alert("adad"); return _navigate.call(this, fragment, opts); } }); })(Backbone.History); 

This code wraps the Backbone.History.navigate method and shows a warning about the method call. But this warning never appears when I change routes.

The console.log line is only for the file to be downloaded after backbone.js.

What is wrong with this code?

+7
source share
1 answer

I think you are redefining the wrong: navigate not used the way you think.

Let's look at the Backbone.history.start part:

 // Start the hash change handling, returning `true` if the current URL matches // an existing route, and `false` otherwise. start: function(options) { //... if (this._hasPushState) { Backbone.$(window).on('popstate', this.checkUrl); } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) { Backbone.$(window).on('hashchange', this.checkUrl); } else if (this._wantsHashChange) { this._checkUrlInterval = setInterval(this.checkUrl, this.interval); } 

You will see that all the different ways of handling routing in Backbone go through checkUrl , not navigate . The checkUrl method does a bit of busy work and calls loadUrl ; One part of the busy work is this:

  if (this.iframe) this.navigate(current); 

therefore, navigate will be called, but only when <iframe> used to simulate hashchange and popstate and AFAIK events, which happens only when you use an older version of IE.

Return to the normal path through the code. We saw that checkUrl does some work and calls loadUrl , so what does it do? loadUrl does this :

 loadUrl: function(fragmentOverride) { var fragment = this.fragment = this.getFragment(fragmentOverride); var matched = _.any(this.handlers, function(handler) { if (handler.route.test(fragment)) { handler.callback(fragment); return true; } }); return matched; } 

If you look at the route method in History and route in route you will see that handler.callback is what calls the route handler from one of your routers and fires a routing event.

The navigate method you are replacing is heavily used by Router navigate :

 navigate: function(fragment, options) { Backbone.history.navigate(fragment, options); return this; } 

If you want to redirect before calling the route handler, you can replace loadUrl with something like this:

 (function(History) { var _loadUrl = History.prototype.loadUrl; _.extend(History.prototype, { loadUrl: function() { var args = [].slice.apply(arguments); args[0] = this.getFragment(args[0]); // If args[0] is the fragment that you want to // redirect then replace it here or do whatever // needs to be done. return _loadUrl.apply(this, args); } }); })(Backbone.History); 

Demo: http://jsfiddle.net/ambiguous/e4KYK/

In general, I think that you better handle redirects in a regular route handler: when an offensive route is called, just call navigate on any router.


Keep in mind that Backbone.History not documented outside the start method, so everything here can be changed.

+2
source

All Articles