最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Backbone.js - extend router with beforeRoute filter - Stack Overflow

matteradmin7PV0评论

I am trying to implement a before filter for my routes in Backbone.js. I found the following code here -

var MyRouter = Backbone.Router.extend({
    route: function(route, name, callback) {
        return Backbone.Router.prototype.route.call(this, route, name, function() {
            this.trigger.apply(this, ['beforeroute:' + name].concat(_.toArray(arguments)));
            callback.apply(this, arguments);
        });
    }
});

However, I am not sure what I need to do next. I'll need to define a function with the "before route" logic I want, but I don't understand how exactly it will be invoked.

I am trying to implement a before filter for my routes in Backbone.js. I found the following code here -

var MyRouter = Backbone.Router.extend({
    route: function(route, name, callback) {
        return Backbone.Router.prototype.route.call(this, route, name, function() {
            this.trigger.apply(this, ['beforeroute:' + name].concat(_.toArray(arguments)));
            callback.apply(this, arguments);
        });
    }
});

However, I am not sure what I need to do next. I'll need to define a function with the "before route" logic I want, but I don't understand how exactly it will be invoked.

Share Improve this question asked Dec 7, 2012 at 20:31 Mark SherrettaMark Sherretta 10.2k4 gold badges40 silver badges42 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

The overridden route function triggers an event named beforeroute:routename, then calls the original route function. So if you have a route like this:

var MyRouter = Backbone.Router.extend({
    routes: { 
        "": "home"
    },
    // ...
});

Then you would subscribe to the beforeroute event using:

var router = new MyRouter()

router.on("beforeroute:home", function() {

    // before route logic here...
    alert("Home route is about to get hit ...");
});

Fiddle demo.

Just for the other people like me are confused, why this not works. (anymore) Since Backbone Version 0.9.10 it seems to be broken. (don't know really why)

But in Version 1.0.0 you can now use function literals instead of references to methods. http://backbonejs/#changelog

So you can do something before you call the Route...

routes: {
   'your-route' : function(){ if(yourCondition){ yourAction(); }}
}

Another way to do that is extending the Router.route function. Below an example for what I needed to do (to check user is authenticated). It's basically the original Backbone code (1.0.0) plus my custom code (marked with ments):

  Backbone.Router.prototype.route = function(route, name, callback) {
    if (!_.isRegExp(route)) route = this._routeToRegExp(route);
    if (_.isFunction(name)) {
      callback = name;
      name = '';
    }
    if (!callback) callback = this[name];
    // here my custom code
    callback = _.wrap(callback, _.bind(function(cb) {
      if (name == 'login' || sessionModel.authenticated()) {
        _.bind(cb, this)();
      } else {
        this.navigate('login', {trigger: true});
      }
    }, this));
    // finish my custom code
    var router = this;
    Backbone.history.route(route, function(fragment) {
      var args = router._extractParameters(route, fragment);
      callback && callback.apply(router, args);
      router.trigger.apply(router, ['route:' + name].concat(args));
      router.trigger('route', name, args);
      Backbone.history.trigger('route', router, name, args);
    });
    return this;
  };

Notice _.wrap and _.bind so this is the one that you would expect when using the router. Otherwise I was getting a "this is undefined" error.

Post a comment

comment list (0)

  1. No comments so far