Penghala dalam Tulang Belakang bertindak sebagai laluan dan mengawal arah URL Ia berkuat kuasa apabila teg # digunakan dalam URL.
Mentakrifkan Penghala memerlukan sekurang-kurangnya Penghala dan fungsi untuk memetakan URL tertentu, dan kita perlu ingat bahawa dalam Backbone, sebarang aksara selepas teg # akan diterima dan ditafsirkan oleh Penghala.
Seterusnya kita mentakrifkan Penghala:
<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>
Sekarang, kami telah menentukan Penghala, tetapi pada masa ini Penghala tidak sepadan dengan URL tertentu Seterusnya, kami akan mula menerangkan secara terperinci cara Penghala berfungsi.
Penghalaan dinamik
Backbone membolehkan anda menentukan Penghala dengan parameter tertentu. Sebagai contoh, anda mungkin ingin menerima siaran dengan id tertentu, seperti URL ini: "http://example.com/#/posts/12". Setelah Penghala diaktifkan, anda boleh mendapatkan siaran dengan id 12 . Seterusnya, mari kita tentukan Penghala ini:
<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>
Peraturan Pemadanan
Backbone menggunakan dua bentuk pembolehubah untuk menetapkan peraturan padanan Penghala. Yang pertama ialah :, yang sepadan dengan mana-mana parameter antara garis miring dalam URL, dan yang satu lagi ialah *, yang sepadan dengan segala-galanya selepas garis miring. Ambil perhatian bahawa kerana bentuk kedua lebih kabur daripada yang pertama, ia mempunyai keutamaan padanan yang paling rendah.
Hasil daripada sebarang bentuk padanan akan dihantar ke fungsi yang berkaitan dalam bentuk parameter Peraturan pertama mungkin mengembalikan satu atau lebih parameter, dan peraturan kedua akan mengembalikan keseluruhan hasil padanan sebagai satu parameter.
Seterusnya, kami menggunakan contoh untuk menggambarkan:
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两个类共同完成的:
我们一般不会直接实例化一个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(); });
Jalankan kod ini dan lawati URL: http://localhost/index.html#topic/5/20 Anda akan mendapati bahawa selepas Tindakan ini dilaksanakan, pemantauan tidak lagi berkesan.