您好,欢迎访问一九零五行业门户网

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

backbone 中的 router 充当路由的作用,控制 url 的走向,当在 url 中使用 # 标签时生效。
定义 router 至少需要一个 router 和一个函数来映射特定的 url,而且我们需要记住,在 backbone 中,# 标签后的任意字符都会被 router 接收并解释。
下面我们来定义一个 router:
<script> var approuter = backbone.router.extend({ routes: { "*actions": "defaultroute" // 匹配 http://example.com/#anything-here } }); // 实例化 router var app_router = new approuter; app_router.on('route:defaultroute', function(actions) { alert(actions); }) // 打开 backbone 的历史记录 backbone.history.start(); </script>
现在,我们就定义好了一个 router 了,但此时 router 并未匹配特定的 url,接下来我们开始详细讲解 router 是如何工作的。
动态路由选择
backbone 允许你定义带有特定参数的 router。例如,你可能希望通过一个特定的 id 接收一个 post,比如这样一个 url:"http://example.com/#/posts/12",一旦这个 router 被激活,你就可以取得一个 id 为12的 post。接下来,我们就来定义这个 router:
<script> var approuter = backbone.router.extend({ routes: { "posts/:id": "getpost", "*actions": "defaultroute" //backbone 会根据顺序匹配路由 } }); // 实例化 router var app_router = new approuter; app_router.on('route:getpost', function (id) { // 注意,参数通过这里进行传递 alert( "get post number " + id ); }); app_router.on('route:defaultroute', function (actions) { alert( actions ); }); // 打开 backbone 的历史记录 backbone.history.start(); </script>
匹配规则
backbone 使用两种形式的变量来设置 router 的匹配规则。第一种是 :,它可以匹配 url 中斜杠之间的任意参数,另一种是 *,它用来匹配斜杠后面的所有部分。注意,由于第二种形式的模糊性大于第一种,所以它的匹配优先级最低。
任一形式匹配的结果会以参数的形式传递到相关的函数中,第一种规则可能返回一个或多个参数,第二种规则将整个匹配结果作为一个参数返回。
接下来,我们用实例来说明:
routes:{ "posts/:id": "getpost", // <a href="http://example.com/#/posts/121">example</a> "download/*path": "downloadfile", // <a href="http://example.com/#/download/user/images/hey.gif">download</a> ":route/:action": "loadview", // <a href="http://example.com/#/dashboard/graph">load route/action view</a> }, app_router.on('route:getpost', function( id ){ alert(id); // 匹配后,传递过来的参数为 12 }); app_router.on('route:downloadfile', function( path ){ alert(path); // 匹配后,整个匹配结果作为一个参数返回,路径为 user/images/hey.gif }); app_router.on('route:loadview', function( route, action ){ alert(route + "_" + action); // 匹配后,传递过来两个参数,此时会弹出 dashboard_graph });
你可能经常听说“路由器”这个词,但它常常是指一种网络设备,这种设备是网络连接、数据传输的导航和枢纽。而backbone中的“路由器”功能与它类似,从上面的例子中你就能看出,它可以将不同的url锚点导航到对应的action方法。
(许多服务端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方法。
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心跳的方式监听。
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方法,例如:
router.route('topic/:pageno/:pagesize', 'page', function(pageno, pagesize){ // todo }); 我们调用route()方法时,给定的规则不仅仅可以是字符串,也可以是一个正则表达式: router.route(/^topic/(.*?)/(.*?)$/, 'page', function(pageno, pagesize){ // todo });
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被执行之后,监听已经不再生效了。
更多全面解析javascript的backbone.js框架中的router路由。
其它类似信息

推荐信息