AngularJS权威指南-作用域

《AngularJS 权威教程》读书笔记,第四章——作用域。

简介

作用域是视图和控制器之间的胶水:在应用将视图渲染并呈献给用户之前,视图中的模板会和作用域进行连接,然后应用会对 DOM 进行设置以便将属性变化通知给 AngularJS。这个功能让 XHR 请求等 promise 对象的实现变得非常容易(学了三天 promise 的我实在不明白这句话啥意思?)。
作用域可以嵌套,所以子作用域可以引用父级作用域中的属性。
作用域提供了监控数据模型变化的能力。它允许开发者使用其中的 apply 机制,将数据模型的变化在整个应用范围内进行通知。我们在作用域的上下文中定义和执行表达式,同时它也是将事件通知给另一个控制器和应用其他部分的中介。

$rootScope

$rootScope 是所有 $scope 对象的最上层。
$rootScope 是 AngularJS 中最接近全局作用域的对象。在 $rootScope 上附加太多业务逻辑并不是好主意,这与污染 JavaScript 全局作用域是一样的。

作用域的作用

作用域有以下基本功能:

  • 提供观察者以监视数据模型的变化
  • 可以将数据模型的变化通知给整个应用,甚至是系统外的组件
  • 可以进行嵌套,隔离业务功能和数据
  • 给表达式提供运算时所需的执行环境

作用域包含了渲染视图时所需的功能和数据,它是所有视图的唯一源头,可以将作用域理解成视图模型(view model)。

作用域声明周期

当 Angular 关心的事件发生在浏览器中时,比如用户在通过 ng-model 属性监控的输入字段中输入,或者带有 ng-click 属性的按钮被点击时,Angular 的事件循环都会启动。这个事件将在 Angular 执行上下文中处理。
每当事件被处理时,$scope 就会对定义的表达式求值。此时事件循环会启动,并且 Angular 应用会监控应用程序内的所有对象,脏值检测循环也会运行。

以上又对 Angular 内部运行机制科普了一波,下面正式说作用域对象的生命周期的四个阶段:

  1. 创建:在创建控制器或指令时,AngularJS 会用 $injector 创建一个新的作用域,并在这个新建的控制器或指令运行时将作用域传递进去。
  2. 链接:当 Angular 开始运行时,所有的 $scope 对象都会附加uozhe链接到视图中。所有创建 $scope 对象的函数也会将自身附加到视图中。这些作用域将会注册当 Angular 应用上下文中发生变化时需要运行的函数(这些函数被称为 $watch 函数,Angular 通过这些函数获知何时启动事件循环)。
  3. 更新:当事件循环运行时,它通常执行在顶层 $scope 对象上(其实就是 $rootScope),每个子作用域都执行自己的脏值检测。每个监控函数都会检查变化。如果检测到任意变化,$scope 对象就会触发指定的回调函数。
  4. 销毁:当一个 $scope 在视图中不再需要时,这个作用域将会清理和销毁自己,(这一步 Angular 会为你处理)。但是知道是谁创建了这个作用域还是有用的,因为你可以使用这个 $scope 上叫做 $destory() 的方法清理这个作用域。

指令和作用域

指令通常不会创建自己的 $scope,但也有例外,比如 ng-controller 和 ng-repeat 指令会创建自己的子作用域并将它们附加到 DOM 元素上。