全面解析JavaScript的Backbone.js框架中的Router路由

这篇文章主要介绍了Backbone.js框架中的Router路由功能,Router在Backbone中至关于一个MVC框架中的Controller控制器功能,须要的朋友能够参考下。html

Backbone 中的 Router 充当路由的做用,控制 URL 的走向,当在 URL 中使用 # 标签时生效。
定义 Router 至少须要一个 Router 和一个函数来映射特定的 URL,并且咱们须要记住,在 Backbone 中,# 标签后的任意字符都会被 Router 接收并解释。
下面咱们来定义一个 Router:前端

 1 <script>
 2  var AppRouter = Backbone.Router.extend({
 3   routes: {
 4    "*actions": "defaultRoute" // 匹配 http://example.com/#anything-here
 5   }
 6  });
 7  // 实例化 Router
 8  var app_router = new AppRouter;
 9  
10  app_router.on('route:defaultRoute', function(actions) {
11   alert(actions);
12  })
13  
14  // 打开 Backbone 的历史记录
15  Backbone.history.start();
16 </script>

如今,咱们就定义好了一个 Router 了,但此时 Router 并未匹配特定的 URL,接下来咱们开始详细讲解 Router 是如何工做的。正则表达式

动态路由选择
Backbone 容许你定义带有特定参数的 Router。例如,你可能但愿经过一个特定的 id 接收一个 post,好比这样一个 URL:"http://example.com/#/posts/12",一旦这个 Router 被激活,你就能够取得一个 id 为12的 post。接下来,咱们就来定义这个 Router:浏览器

 1 <script>
 2  var AppRouter = Backbone.Router.extend({
 3   routes: {
 4    "posts/:id": "getPost",
 5    "*actions": "defaultRoute" //Backbone 会根据顺序匹配路由
 6   }
 7  });
 8  // 实例化 Router
 9  var app_router = new AppRouter;
10  app_router.on('route:getPost', function (id) {
11   // 注意,参数经过这里进行传递
12   alert( "Get post number " + id ); 
13  });
14  app_router.on('route:defaultRoute', function (actions) {
15   alert( actions ); 
16  });
17  // 打开 Backbone 的历史记录
18  Backbone.history.start();
19 </script>

匹配规则
Backbone 使用两种形式的变量来设置 Router 的匹配规则。第一种是 :,它能够匹配 URL 中斜杠之间的任意参数,另外一种是 *,它用来匹配斜杠后面的全部部分。注意,因为第二种形式的模糊性大于第一种,因此它的匹配优先级最低。
任一形式匹配的结果会以参数的形式传递到相关的函数中,第一种规则可能返回一个或多个参数,第二种规则将整个匹配结果做为一个参数返回。
接下来,咱们用实例来讲明:网络

 1 routes:{
 2  
 3  "posts/:id": "getPost",
 4  // <a href="http://example.com/#/posts/121">Example</a>
 5  
 6  "download/*path": "downloadFile",
 7  // <a href="http://example.com/#/download/user/images/hey.gif">Download</a>
 8  
 9  ":route/:action": "loadView",
10  // <a href="http://example.com/#/dashboard/graph">Load Route/Action View</a>
11  
12 },
13  
14 app_router.on('route:getPost', function( id ){ 
15  alert(id); // 匹配后,传递过来的参数为 12
16 });
17 app_router.on('route:downloadFile', function( path ){ 
18  alert(path); // 匹配后,整个匹配结果做为一个参数返回,路径为 user/images/hey.gif 
19 });
20 app_router.on('route:loadView', function( route, action ){ 
21  alert(route + "_" + action); // 匹配后,传递过来两个参数,此时会弹出 dashboard_graph 
22 });

你可能常常据说“路由器”这个词,但它经常是指一种网络设备,这种设备是网络链接、数据传输的导航和枢纽。而Backbone中的“路由器”功能与它相似,从上面的例子中你就能看出,它能够将不一样的URL锚点导航到对应的Action方法。
(许多服务端Web框架中也提供了这样的机制,但Backbone.Router更侧重前端单页应用的导航。)app

Backbone的路由导航是由Backbone.Router和Backbone.History两个类共同完成的:框架

  • Router类用于定义和解析路由规则,并将URL映射到Action。
  • History类用于监听URL的变化,和触发Action方法。

咱们通常不会直接实例化一个History,由于咱们在第一次建立Router实例时,会自动建立一个History的单例对象,你能够经过Backbone.history来访问这个对象。函数

要使用路由功能,首先咱们须要定义一个Router类来声明须要监听的URL规则和Action,在刚才的例子中,咱们在定义时经过routes属性来定义须要监听的URL列表,其中Key表示URL规则,Value表示当URL处于该规则时所执行的Action方法。post

Hash规则
URL规则表示当前URL中的Hash(锚点)片断,咱们除了能在规则中指定通常的字符串外,还须要注意两种特别的动态规则:
规则中以/(斜线)为分隔的一段字符串,在Router类内部会被转换为表达式([^\/]+),表示以/(斜线)开头的多个字符,若是在这一段规则中设置了:(冒号),则表示URL中这一段字符串将被做为参数传递给Action。
例如咱们设置了规则topic/:id,当锚点为#topic/1023时,1023将被做为参数id传递给Action,规则中的参数名(:id)通常会和Action方法的形参名称相同,虽然Router并无这样的限制,但使用相同的参数名更容易让人理解。
规则中的*(星号)会在Router内部被转换为表达式(.*?),表示零个或多个任意字符,与:(冒号)规则相比,*(星号)没有/(斜线)分隔的限制,就像咱们在上面的例子中定义的*error规则同样。
Router中的*(星号)规则在被转换为正则表达式后使用非贪婪模式,所以你可使用例如这样的组合规则:*type/:id,它能匹配#hot/1023,同时会将hot和1023做为参数传递给Action方法。spa

上面介绍了规则的定义方式,这些规则都会对应一个Action方法名称,该方法必须处于Router对象中。
在定义好Router类以后,咱们须要实例化一个Router对象,并调用Backbone.history对象的start()方法,该方法会启动对URL的监听。在History对象内部,默认会经过onhashchange事件监听URL中Hash(锚点)的变化,对于不支持onhashchange事件的浏览器(例如IE6),History会经过setInterval心跳的方式监听。

pushState规则
Backbone.History还支持pushState方式的URL,pushState是HTML5提供的一种新特性,它能操做当前浏览器的URL(而不是仅仅改变锚点),同时不会致使页面刷新,从而使单页应用使用起来更像一套完整的流程。
要使用pushState特性,你须要先了解HTML5为该特性提供的一些方法和事件(这些方法都被定义在window.history对象中):

1.pushState():该方法能够将指定的URL添加一个新的history实体到浏览器历史里
2.replaceState():该方法能够将当前的history实体替换为指定的URL

调用pushState()和replaceState()方法,仅仅是替换当前页面的URL,而并不会真正转到这个URL地址(当使用后退或前进按钮时,也不会跳转到该URL),咱们能够经过onpopstate事件来监听这两个方法引发的URL变化。

路由相关方法

1.route()方法
在设定好路由规则以后,若是须要动态调整,能够调用Router.route()方法来动态添加路由规则及Action方法,

例如:

1 router.route('topic/:pageno/:pagesize', 'page', function(pageno, pagesize){ 
2  // todo 
3 }); 
4 咱们调用route()方法时,给定的规则不只仅能够是字符串,也能够是一个正则表达式:
5 router.route(/^topic/(.*?)/(.*?)$/, 'page', function(pageno, pagesize){ 
6  // todo 
7 }); 

2.navigate()方法
在前面的例子中,URL规则都是由咱们手动输入触发的,在实际应用中,有时可能须要手动进行跳转、导航,这时能够调用

Router.navigate()方法进行控制,例如:
router.navigate('topic/1000', { 
 trigger: true
}); 

这段代码将URL更改成http://localhost/index.html#topic/1000,并触发了renderDetail方法。须要注意的是,咱们在第二个参数传入了trigger配置,该配置用于表示更改URL的同时是否触发相应的Action方法。

3.stop()方法
还记得咱们是经过Backbone.history.start()方法来启动路由监听的,你也能够随时调用Backbone.history.stop()方法来中止监听,例如:

router.route('topic/:pageno/:pagesize', 'page', function(pageno, pagesize) { 
 Backbone.history.stop(); 
}); 

运行这段代码,并访问URL:http://localhost/index.html#topic/5/20,你会发现这个Action被执行以后,监听已经再也不生效了。

相关文章
相关标签/搜索