Backbone.js:获取当前路线

使用Backbone,我可以得到当前路由的名称吗? 我知道如何绑定到路由更改事件,但是我希望能够在其他时间和更改之间确定当前路由。

如果您在应用程序中实例化了一个路由器,则以下行将返回当前片段:

Backbone.history.getFragment(); 

从Backbone.js文档 :

“[…] History作为一个全局路由器(每帧)来处理hashchange事件或pushState,匹配适当的路由,并触发callback。你不应该永远不必自己创build其中的一个 – 你应该使用引用到Backbone.history,如果你使用路由器将会自动为你创build […]“

如果你需要绑定到这个片段的函数的名字,你可以在你的路由器的范围内做这样的事情:

 alert( this.routes[Backbone.history.getFragment()] ); 

或者从你的路由器外面这样做:

 alert( myRouter.routes[Backbone.history.getFragment()] ); 

罗伯特的答案是有趣的,但遗憾的是,只有散列与路由中定义的一样才有效。 例如,如果你有一个user(/:uid)pathuser(/:uid) ,如果Backbone.history.fragment"user""user/1" (这两个都是最明显的用例路线)。 换句话说,如果哈希正好是"user(/:uid)" (极不可能),它只会find适当的callback名称。

因为我需要这个function,所以我用一个current函数扩展了Backbone.Router ,这个函数重用了历史和路由器对象用于匹配当前片段和定义的路由的一些代码,以触发适当的callback。 对于我的用例,它采用可选参数route ,如果设置为true,将返回为路由定义的相应函数名称。 否则,它将从Backbone.History.fragment返回当前散列片段。

您可以将代码添加到现有的Extend中,在此初始化和设置Backbone路由器。

 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' 

我相信可以做一些改进,但这是一个很好的开始的方法。 另外,创build这个function很容易,不需要扩展Route对象。 我这样做是因为这是我设置最方便的方式。

我还没有完全testing过,所以请让我知道,如果南下。


更新04/25/2013

我对函数做了一些修改,所以我没有返回散列或者路由callback名称,而是返回一个带有fragment,params和route的对象,这样就可以访问当前路由中的所有数据,就像你从route-事件。

你可以看到下面的变化:

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

看到前面的代码进一步的评论和解释,他们看起来大致相同。

要从被调用的路由处理程序获取调用路由(或url),可以通过检查来获取它

 Backbone.history.location.href ...完整的url
 Backbone.history.location.search ...查询string从?

我在这里find这个答案,所以我想我应该离开我发现的东西。

如果您使用路由器的根设置,您也可以包含它来获得“真实”的片段。

 (Backbone.history.options.root || "") + "/" + Backbone.history.fragment 

这里有一个更详细的(或者,根据你的口味,更可读) 西蒙的答案版本:

 current: function () { var fragment = Backbone.history.fragment, routes = _.pairs(this.routes), route, name, found; found = _.find(routes, function (namedRoute) { route = namedRoute[0]; name = namedRoute[1]; if (!_.isRegExp(route)) { route = this._routeToRegExp(route); } return route.test(fragment); }, this); if (found) { return { name: name, params: this._extractParameters(route, fragment), fragment: fragment }; } } 

如果您查看Router的源代码,您将看到当路由器触发事件​​说事物发生了变化时,它将名称作为“路由:名称”传递。

http://documentcloud.github.com/backbone/docs/backbone.html#section-84

您始终可以挂接路由器上的“路由”事件并将其存储以获取当前路由。