在设计单页面WEB应用时如果只选用ajax进行异步数据请求,那么用户的体验是相当不好的。对于用户来说,点击了相关的按钮或者链接之后,相应的界面发生了变化,虽然这里使用到ajax的异步请求但是对于用户来说,他可能会认为这是另外一个页面,所以很自然地会进行分享、保存、后退、前进等常规操作。那么,问题来了!这次打开的界面竟然和之前的页面不太一样,也就是页面初始化了,这当然不是我们想要的。
利用Backbone.js框架可以帮助我们完成这样的需求,Backbone的相关介绍我这里就不做赘述了,可以点击链接查看教程!这篇文章主要介绍路由的基本使用。在设置路由之前,我们必须获得一个路由模板,可以从Backbone的Router里面继承得到
var AppRouter = Backbone.Router.extend();//这里得到的是一个类,所以首字母大写
这是一个空的路由模板,即除了继承到的内容,没有其他内容。Backbone允许你定义带有特定参数的Router。
例如,你可能希望通过一个特定的id
接收一个post,
比如这样一个url:"http:localhost/test/#posts/121"
,一旦这个Router
被激活,你就可以取得一个id
为12的post
var AppRouter = Backbone.Router.extend({
routes: {
"posts/:id": function(id) {
console.log(id); // 匹配后,传递过来的参数为 12
},
// Example
"download/*path": function(path) {
console.log(path); // 匹配后,整个匹配结果作为一个参数返回,路径为 user/images/hey.gif
},
// Download
":route/:action": function(route, action) {
console.log(route + "_" + action); // 匹配后,传递过来两个参数,此时会弹出 dashboard_graph
},
// Load Route/Action View
"*other": function(other) {
alert('other');
}
}
});
接下来需要实例化一个Router对象,使用下面的代码得到一个实例并且打开路由
var app_router = new AppRouter();
Backbone.history.start();
另外,也可以动态进行路由注册
app_router.route("fs/:id", function(id) {
console.log('fs--------------->' + id);
})
Backbone使用两种形式的变量来设置Router的匹配规则,第一种是 :,它可以匹配url中斜杠之间的任意参数,另一种是 * ,它用来匹配斜杠后面的所有部分。由于第二种形式的模糊度大于第一种,所以它的匹配优先级是最低的。任意形式的匹配结果会以参数的形式传递到相关的函数中,第一种规则可能返回一个或多个参数,第二种规则则将整个匹配结果当做一个参数返回。一般我们习惯将匹配符后面添加一个变量,用来表示匹配之后的参数变量。当然,你也可以用下面这种方式实现
var AppRouter = Backbone.Router.extend({
routes: {
"posts/:id": "getPost",
// Example
"download/*path": "downloadFile",
// Download
":route/:action": "loadView",
// Load Route/Action View
},
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
});
});
var app_router = new AppRouter();
Backbone.history.start();
值得一提的是,在构造Router类的时候可以传递一个execute函数,有了该函数,匹配到结果后不会执行绑定的router方法,而是执行该execute方法。该方法是个回调函数,接收两个参数,第一个参数是该url指定的路由被注册的函数体,第二个参数为匹配的参数。
var AppRouter = Backbone.Router.extend({
routes: {
"posts/:id": function(id) {
console.log(id); // 匹配后,传递过来的参数为 12
},
// Example
"download/*path": function(path) {
console.log(path); // 匹配后,整个匹配结果作为一个参数返回,路径为 user/images/hey.gif
},
// Download
":route/:action": function(route, action) {
console.log(route + "_" + action); // 匹配后,传递过来两个参数,此时会弹出 dashboard_graph
},
// Load Route/Action View
"*other": function(other) {
alert('other');
}
},
execute: function(callback, args) {
console.log('匹配成功,会执行execute方法');
// 解开以下两句注释,看看这两个参数是什么
// console.log(callback);
// console.log(args);
callback.apply(this, args);// 执行绑定的方法
}
});
如果url内容为http://localhost/learn/backbone/demo04/index.html#/fs/123,那么执行的结果如下:
解开上面两行注释,执行结果如下: