Router和History (路由控制)-backbone


 Router和History (路由控制)html

  Backbone.Router担任了一部分Controller(控制器)的工做,它通常运行在单页应用中,能将特定的URL或锚点规则绑定到一个指定的方法(后文中称Action)。前端

  当咱们开发一个单页应用时,经常会遇到这样两个问题:正则表达式

 

  咱们在同一个页面中经过用户的操做来隐藏、显示HTML块,为用户提供一个无刷新、完整流畅的体验,但用户可能并不知道他当前正处于同一个页面中,所以他但愿经过浏览器的“前进”和“后退”按钮来返回和前进到上一步操做。当他真正这样操做时,会离开当前页面,这显然不是用户所指望的。浏览器

 

  另外一个问题是用户在单页应用中操做,当他读到一篇好的文章,或看到一个中意的商品时,他可能会将URL收藏起来或分享给本身的好友。但当他下一次从新打开这个连接地址,看到的倒是应用的初始化状态,而并非当初那篇文章或那个商品。服务器

 

  Backbone.Router为咱们提供了解决这两个问题的方法,咱们先来看一个例子:网络

  1. var AppRouter = Backbone.Router.extend({ routes : { renderList : function() { console.log('渲染列表方法'); }, renderDetail : function(id) { console.log('渲染详情方法, id为: ' + id); }, renderError : function(error) { console.log('URL错误, 错误信息: ' + error); } }); 
复制代码

将例子中的代码复制到你的页面中。假设你的页面地址为http://localhost/index.html,请依次访问下面的地址,并注意控制台的输出结果:框架

 

  • http://localhost/index.html // 输出:应用入口方法
  • http://localhost/index.html#topic // 输出:渲染列表方法
  • http://localhost/index.html#topic/1023 // 输出:渲染详情方法, id为:1023
  • http://localhost/index.html#about // 输出:URL错误, 错误信息: about

 

  而后再使用浏览器的“前进”、“返回”等按钮进行切换,你会看到当你的URL切换时,控制台输出了对应的结果,说明它已经调用了相应的方法。而在进行这些操时,页面并无刷新。这个例子很好地解决了咱们在一开始所说的两个问题。spa

 

10.1 路由规则设定code

  你可能常常据说“路由器”这个词,但它经常是指一种网络设备,这种设备是网络链接、数据传输的导航和枢纽。而Backbone中的“路由器”功能与它相似,从上面的例子中你就能看出,它能够将不一样的URL锚点导航到对应的Action方法。router

 

  (许多服务端Web框架中也提供了这样的机制,但Backbone.Router更侧重前端单页应用的导航。)

 

  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方法。

10.2 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方法。

 

  上面介绍了规则的定义方式,这些规则都会对应一个Action方法名称,该方法必须处于Router对象中。

 

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


10.3 pushState规则

  Backbone.History还支持pushState方式的URL,pushState是HTML5提供的一种新特性,它能操做当前浏览器的URL(而不是仅仅改变锚点),同时不会致使页面刷新,从而使单页应用使用起来更像一套完整的流程。

 

  要使用pushState特性,你须要先了解HTML5为该特性提供的一些方法和事件(这些方法都被定义在window.history对象中):

 

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

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

 

  值得注意的是,使用pushState特性时,须要在服务器端对URL规则进行配置,不然用户在下一次访问该地址时,可能没法正确导航到当前页面。另外低于如下版本的浏览器是不支持该特性的:Chrome 5,Firefox 4.0,IE 10,Opera 11.5,Safari 5.0

 

  关于pushState规则这里再也不深刻讨论,若是须要了解,请参考我所注释的Backbone源码。


10.4 路由相关方法

  route()方法

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

 

  1. router.route('topic/:pageno/:pagesize', 'page', function(pageno, pagesize){  
  2.     // todo  
  3. });  
复制代码

咱们调用route()方法时,给定的规则不只仅能够是字符串,也能够是一个正则表达式:

  1. router.route(/^topic/(.*?)/(.*?)$/, 'page', function(pageno, pagesize){ // todo }); 
复制代码

 navigate()方法

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

 

  1. router.navigate('topic/1000', {  
  2.      trigger: true  
  3. });
复制代码

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

 

  stop()方法

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

 

原文http://sun80264629.iteye.com/blog/1883204

相关文章
相关标签/搜索