Backbone 学习笔记 05

"Backbone 提供了一套完整的 MVC结构的 Web开发框架"

Posted by 刘一凡 on April 18, 2016

Backbone 学习笔记 05

导航控制器


前面说过, Backbone 框架的最佳应用场景应该是构建一个逻辑复杂的单页面应用。
Backbone 中提供了两个重要的类模型, 导航控制器(Router) 和 历史(history), Router 封装了兼容各类浏览器 history 的方法, 通过浏览器的 hash 对象和 HTML5 中的 pushState 方法, 将某阶段特殊的 URL 或描点地址与既定的事件(event) 或函数(action) 相绑定。输入这些 URL 地址时, 对应完成不同的功能。

浏览器导航基础


在正式介绍 Backbone 中的导航控制器(router), 有必要了解下浏览器的导航功能基础知识, 包含浏览器窗口(window)的 history, HTML5 中的 history API 和 location 对象。了解这些有利于对 Backbone 中的导航控制器工作原理的理解和掌握。

history 对象

在 JavaScript 中, history 对象用于保存浏览器历史记录。
其中有两个方法 backforward

back 方法用于返回浏览器历史记录中当前页的上一页, 与浏览器的”后退”按钮功能相同。

window.history.back()

forward 方法是进入浏览器历史记录中当前页的下一页, 与浏览器的”前进”按钮功能相同。

window.history.forward()

go 方法也能实现页面的前进和后退, 调用格式 :

window.history.go(n)

n 为一个整数, 大于 0 表示前进, 小于 0 表示后退。

HTML 5 中的 history 对象 API

HTML5 基于原有对象方法新增了两个实用的 API 方法 :

pushState 方法 : 功能是向历史记录堆栈的顶部添加一条记录, 常用于实现页面的无刷新跳转

window.history.pushState(data, title, [, url])

其中 data 参数表示再添加记录时传递的数据对象, 该对象通常为 JSON 格式的字符串, 参数 title 为页面显示的标题, 可选参数为页面跳转链接, 默认为当前页地址。

replaceState 方法 : 功能是修改当前页面的历史记录值

window.history.replaceState(data, title, [, url])

history 对象还有一个重要的 state 属性, 通过该属性可以获取使用 pushState 方法新增的实体对象内容, 即在使用 pushState 时的 data 参数的实体值, 他的调用格式为 :

window.history.state

各个浏览器对 HTML5 标准支持不全面, 在使用 history 对象两个新增的 API 方法时, 需要检测浏览器的支持状态 :

funtion support_history_api(){
    return !!(window.history && history.pushState)
}

location 对象

在浏览器窗口中, location 对象的功能是管理浏览器的地址。该对象拥有很多实用的属性和方法, 比如 href 属性和 reload 方法等, 前者可获取当前浏览器地址, 后者方法可以重新按地址加载。

绑定导航地址


前面的章节, 使我们了解了浏览器窗口的 historylocation对象属性和方法的实用, 在 Backbone 框架中构建 router 类时, 大量封装了这两种对象的属性和方法, 将页面特定的 url 或 hash 属性与定义好的 action 或 events 相绑定。在地址栏浏览这些 URL 时, 绑定的 action 对应的函数或执行相应的事件, 可以实现无刷新加载新内容, 以及收藏特定 URL 片段的功能。

action 方式绑定 URL 地址

所谓 action 方式, 是将页面特定的 URL 或 hash 属性与一个对应的函数(动作)相绑定, 即在构建 router 类时, 通过添加 routes 属性, 在属性中声明 URL 或 hash 属性和函数的对应关系, 这样就完成了两者间的绑定。一旦绑定完成, 在浏览器中浏览对应的 URL 地址时, 执行对应函数中的代码。

示例一 : actions 方式绑定 URL 地址

演示代码

event 方式绑定 URL 地址

在构建 router 类中, 通过添加 routes 属性声明需要监听的 URL 地址列表时, 每绑定一个对象的 key/value 关系, 会触发一个基于动作(action) 函数名的事件。实例化后的 router 类对象可以绑定该事件, 并在事件中还可以接收 URL 地址传来的实参数据。

示例二 : event 方式绑定 URL 地址

演示代码

定义 hash 属性绑定规则

构建 router 类并添加 routes 属性来声明需要监听的 URL 地址列表时, 被监听的 key 部分用于定义当前 URL 地址中 hash 属性的规则。在该规则中, 需要注意以下几种特殊字符代表的含义。

/ 反斜杠表示内容的分割, 该字符串在 router 类内部会自动转换成 “([^\/])” 表达式, 例如定义如下匹配的规则 :

"#search/a/b/c" : "search_a_b_c"

必须在地址栏中输入如下地址 :

http://localhost/XX.html#search/a/bc

: 冒号表示该段内容将以参数的形式传递给对应的动作(action)函数, 而函数也可以通过以回调参数方式进行接收。例如 :

"#search/:a/m:b/n:c" : "search_a_m_n" 

必须在地址栏中输入如下地址 :

http://localhost/XX.html#search/1/m2/n3

在该函数中, 形参 a 对应实参 1, 形参 m 对应实参 2, 形参 n 对应实参 3.

* 星号表示零个或多个任意字符串

示例三 : 定义 hash 属性绑定规则

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Router</title>
    <style>
    div{
      font-size: 13px;
      margin: 5px 0;
    }
    </style>
    <script src="http://apps.bdimg.com/libs/jquery/1.9.0/jquery.min.js"></script>
    <script src="http://apps.bdimg.com/libs/underscore.js/1.7.0/underscore-min.js"></script>
    <script src="http://apps.bdimg.com/libs/backbone.js/1.0.0/backbone-min.js"></script>
</head>
<body>
<div>
  <a href="#abc/p5">其他页</a>
</div>
<div id="divShow"></div>
<script>
  var $divShow = $("#divShow");
  var testrouter = Backbone.Router.extend({
    routes : {
      "*path/p:page" : "search_other"
    },
    search_other : function(path, page){
      $divShow.html("路径名为 " + path + " , 页码为 " + page);
    }
  });
  var router = new testrouter();
  Backbone.history.start();
</script>
</body>
</html>

### router 类中的方法

---

在 Backbone 框架中的 router 类中, 通过添加 `routes` 属性声明 url 中 hash 属性的匹配规则列表, 当页面中的 url 的 hash 属性处于设置好的规则时, 就可以触发绑定的函数。虽然这种方式是在构建类时进行声明, 但也能通过调用 router 类提供的方法进行修改。`router` 类提供了两个用于修改 url 中的 hash 属性的匹配规则的方法, 一个是 route 方法, 另一个是 `navigate` 方法, 接下来介绍这两方法。

#### route 方法的使用

在 router 类, route 方法的功能是动态修改 `url` 中 `hash` 属性的匹配规则和动作(action)函数, 该方法的调用格式如下 : 

    objrouter.route(route, name, callback)

其中参数 `objrouter` 是实例化后的导航对象, 括号中的 `route` 参数为匹配规则内容, 该规则可以与 `routes` 属性声明时相同, 可以用正则表达式声明, 参数 `name` 为规则的名称, `callback` 表示匹配规则对应执行的动作函数(action)

示例四 : 使用 route 方法声明匹配规则和执行函数

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Router</title>
        <style>
        div{
          font-size: 13px;
          margin: 5px 0;
        }
        </style>
        <script src="http://apps.bdimg.com/libs/jquery/1.9.0/jquery.min.js"></script>
        <script src="http://apps.bdimg.com/libs/underscore.js/1.7.0/underscore-min.js"></script>
        <script src="http://apps.bdimg.com/libs/backbone.js/1.0.0/backbone-min.js"></script>
    </head>
    <body>
    <div>
      <a href="">首页</a>
      <a href="#search">查询列表</a>
      <a href="#search/abc/p2">页码关键字查询</a>
    </div>
    <div id="divShow"></div>
    <script>
      var $divShow = $("#divShow");
      var testrouter = Backbone.Router.extend({
        routes : {
          "" : "main",
          "search/:key" : "search_key"
        },
        initialize : function(){
          this.route("search", "search_list", function(){
            $divShow.html("初始化时, 查询列表")
          })
        },
        main : function(){
          $divShow.html("首页");
        },
        search_key : function(key){
          $divShow.html("查询关键字为 " + key + " 记录")
        }
      });
      var router = new testrouter();
      router.route("search/:key/p:page", "search_key_page", function(key, page){
        $divShow.html("实例化, 查询关键字为 " + key + " 记录, 页码为 " + page)
      })
      Backbone.history.start();
    </script>
    </body>
    </html>

在 router 类中, navigate 方法的功能是自动跳换到指定 hash 属性中, 并通过方法中的配置对象设置是否执行与 hash 属性匹配规则对应的动作函数, 调用格式如下 :

objrouter.navigate(fragment, option)

其中, objrouter 参数是实例化后的导航对象; 参数 fragment 表示 url 片段, 即指定的 hash 属性值, options 参数为方法的配置对象。如果在该对应中, 将 trigger 属性值设置为 true , 将执行与 hash 属性匹配规则对应的动作函数, 否则不执行。