Robert's answer 很有趣,但遗憾的是,它只有在哈希与路由中定义的完全一致时才有效。例如,如果您有 user(/:uid) 的路由,则如果 Backbone.history.fragment 是 "user" 或 "user/1"(这两个都是此类路由的两个最明显的用例),则不会匹配。换句话说,只有当哈希值正好是"user(/:uid)"(极不可能)时,它才会找到适当的回调名称。
因为我需要这个功能,所以我用 current 函数扩展了 Backbone.Router,它重用了 History 和 Router 对象用来将当前片段与定义的路由匹配以触发适当的回调的一些代码。
对于我的用例,它采用可选参数route,如果设置为任何真实值,将返回为路由定义的相应函数名称。否则,它将从Backbone.History.fragment 返回当前的哈希片段。
您可以将代码添加到您现有的扩展中,并在其中初始化和设置主干路由器。
var Router = new Backbone.Router.extend({
// Pretty basic stuff
routes : {
"home" : "home",
"user(:/uid)" : "user",
"test" : "completelyDifferent"
},
home : function() {
// Home route
},
user : function(uid) {
// User route
},
// Gets the current route callback function name
// or current hash fragment
current : function(route){
if(route && Backbone.History.started) {
var Router = this,
// Get current fragment from Backbone.History
fragment = Backbone.history.fragment,
// Get current object of routes and convert to array-pairs
routes = _.pairs(Router.routes);
// Loop through array pairs and return
// array on first truthful match.
var matched = _.find(routes, function(handler) {
var route = handler[0];
// Convert the route to RegExp using the
// Backbone Router's internal convert
// function (if it already isn't a RegExp)
route = _.isRegExp(route) ? route : Router._routeToRegExp(route);
// Test the regexp against the current fragment
return route.test(fragment);
});
// Returns callback name or false if
// no matches are found
return matched ? matched[1] : false;
} else {
// Just return current hash fragment in History
return Backbone.history.fragment
}
}
});
// Example uses:
// Location: /home
// console.log(Router.current()) // Outputs 'home'
// Location: /user/1
// console.log(Router.current(true)) // Outputs 'user'
// Location: /user/2
// console.log(Router.current()) // Outputs 'user/2'
// Location: /test
// console.log(Router.current(true)) // Outputs 'completelyDifferent'
我确信可以进行一些改进,但这是帮助您入门的好方法。此外,无需扩展 Route 对象即可轻松创建此功能。我这样做是因为它是我设置的最方便的方式。
我尚未对此进行全面测试,所以如果有任何问题请告诉我。
2013 年 4 月 25 日更新
我对函数做了一些更改,因此我没有返回哈希或路由回调名称,而是返回一个带有片段、参数和路由的对象,这样您就可以从当前路由访问所有数据,就像您从路线事件。
你可以看到下面的变化:
current : function() {
var Router = this,
fragment = Backbone.history.fragment,
routes = _.pairs(Router.routes),
route = null, params = null, matched;
matched = _.find(routes, function(handler) {
route = _.isRegExp(handler[0]) ? handler[0] : Router._routeToRegExp(handler[0]);
return route.test(fragment);
});
if(matched) {
// NEW: Extracts the params using the internal
// function _extractParameters
params = Router._extractParameters(route, fragment);
route = matched[1];
}
return {
route : route,
fragment : fragment,
params : params
};
}
更多 cmets 和解释请参见前面的代码,它们看起来基本相同。