再看backbone的路由配置部分
1 调整options, 记录映射关系; 绑定映射关系给history; 初始化
var Router r = function(options) { options || (options = {}); if (options.routes) this.routes = options.routes;// 键值对式的导航规则 映射到处理函数上 this._bindRoutes(); this.initialize.apply(this, arguments); };
2
// Cached regular expressions for matching named param parts and splatted // parts of route strings. var optionalParam = /((.*?))/g; var namedParam = /((?)?:w+/g; var splatParam = /*w+/g; var escapeRegExp = /[-{}[]+?.,\^$|#s]/g;
3 Router.prototype = {},
初始化,并且手动绑定一个路由到一个回调函数
initialize: function(){}, // Manually bind a single named route to a callback. For example: // // this.route('search/:query/p:num', 'search', function(query, num) { // ... // }); // 导航 指定路由规则 和routes的效果相同 规则也一样 route: function(route, name, callback) { // route要是正则表达式 if (typeof name === 'function') { callback = name; name = ''; } if (!callback) callback = this[name]; var router = this; history.route(route, function(fragment) { var args = router._extractParameters(route, fragment); callback && callback.apply(router, args); router.trigger.apply(router, ['route:' + name].concat(args)); // 触发router的route事件 router.trigger('route', name, args); // 触发history的route事件 history.trigger('route', router, name, args); }); return this; },
2手动到达应用程序某个位置
navigate: function(fragment, options) { history.navigate(fragment, options); return this; },
3 绑定映射给history
// 绑定所有的routes _bindRoutes: function() { if (!this.routes) return; var route, routes = Object.keys(this.routes); while ((route = routes.pop()) != null) { this.route(route, this.routes[route]); } },
3 将虚拟url转换为正则
// 将route字符串转成正则表达式 _routeToRegExp: function(route) { route = route.replace(escapeRegExp, '\$&') // 将 - { } [ ] + ? . , ^ $ # 空格 等进行转义 .replace(optionalParam, '(?:$1)?') // 规则中的括号部分 也就是可有可没有的部分 .replace(namedParam, function(match, optional){ // 将不带括号部分的 但是:...形式的进行替换可以匹配为非/以外任意字符 return optional ? match : '([^/]+)'; })// .replace(splatParam, '(.*?)');// 将*...形式的替换为除换行以外的任何字符匹配.* return new RegExp('^' + route + '$'); // 构建正则 加上 开始^和结束$ },
4 正则匹配fragment,取出参数部分
// 返回decode后的一些URL信息(通过和route匹配的fragment做处理) _extractParameters: function(route, fragment) { var params = route.exec(fragment).slice(1); return _.map(params, function(param) { return param ? decodeURIComponent(param) : null; }); }