2012-12-07 21 views
3

我想在Backbone.js中爲我的路由實現一個過濾器。我發現下面的代碼here -Backbone.js - 用beforeRoute過濾器擴展路由器

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); 
     }); 
    } 
}); 

但是,我不知道我下一步需要做。我需要用我想要的「before route」邏輯來定義一個函數,但我不明白它將如何被調用。

回答

6

重載的route函數觸發一個名爲beforeroute:routename的事件,然後調用原始的route函數。所以,如果你有這樣的路線:

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

那麼你會使用訂閱beforeroute事件:

var router = new MyRouter() 

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

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

Fiddle demo.

+0

完美,謝謝! –

0

只是爲了其他人跟我一樣感到困惑,爲什麼這不起作用。 (已有) 自從骨幹版本0.9.10它似乎被打破。 (不知道爲什麼)

但是在版本1.0.0中,您現在可以使用函數文字而不是引用方法。 http://backbonejs.org/#changelog

所以,你可以做你所說的路線前的東西...

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

另一種方式來做到這一點是擴展Router.route功能。下面是我需要做的一個例子(以檢查用戶是否被認證)。它基本上是原來的骨幹代碼(1.0.0),再加上我的自定義代碼(標有註釋):

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; 
    }; 

通知_.wrap_.bind所以this是使用路由器時,你會期望之一。否則,我得到了「這是未定義的」錯誤。