js路由—backbone的路由的實現02

再看backbone的路由配置部分正則表達式

1 調整options, 記錄映射關係; 綁定映射關係給history; 初始化express

 var Router r = function(options) {
    options || (options = {});
    if (options.routes) this.routes = options.routes;// 鍵值對式的導航規則 映射處處理函數上
    this._bindRoutes();
    this.initialize.apply(this, arguments);
  };

app

  // 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 = {},函數

 初始化,而且手動綁定一個路由到一個回調函數this

    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 綁定映射給historyurl

// 綁定全部的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轉換爲正則spa

 // 將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,取出參數部分prototype

// 返回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;
      });
    }
相關文章
相關標籤/搜索