控制器:
就像 JavaScript 里的构造函数一般,用来增强作用域(scope),当一个控制器通过 ng-controller 指令来添加到 DOM 中时,
ng 会调用该控制器的构造函数来生成一个控制器对象,且会创建一个新的子级作用域
注:在这个构造函数中,作用域会作为 $scope 参数注入其中,并允许用户代码访问它
使用控制器:
1、初始化 $scope 对象
// 设置属性 attrName 的值为 value $scope.attrName = value;
2、为 $scope 对象添加行为(方法)
// 添加方法 func $scope.func = function([params]) {...}
任何对象(或原生类型的变量)被添加到 scope 后都将成为 scope 的属性,作为数据模型供模板/视图调用
任何方法被添加到 scope 后,也能在模板/视图中通过 Angular 表达式或是 Angular 的事件处理器调用
注:Angular的模板是一个声明式的视图,它指定信息从模型、控制器变成用户在浏览器上可以看见的视图
千万不要使用控制器的场合:
1、任何形式的 DOM 场合:控制器只应包含业务逻辑
2、格式化输入:使用 Angular 表单控件代替
3、过滤输出:使用 Angular 过滤器代替
4、在控制器间复用有状态或无状态的代码:使用 Angular 服务代替
5、管理其它部件的生命周期
注:可通过将那些不属于控制器的逻辑都封装到服务中,然后在控制器中通过依赖注入(DI)调用相关服务来保持控制器的“纯度”
实现控制器和 scope 对象的关联:
1、ngController 指令:创建一个新的 scope
2、$route 路由服务
作用域(scope):
1、一个存储应用数据模型的对象
2、为表达式提供一个执行上下文
3、作用域的层级对应于 DOM 的树结构
4、作用域可监听表达式的变化并传播事件
补充:
1、作用域提供了($watch)方法监听数据模型的变化
2、作用域提供了($apply)方法把不是由 Angular 触发的数据模型的改变引入 Angular 的控制范围
3、作用域提供了基于原型链继承其父作用域属性的机制
4、作用域提供了表达式的执行环境,必须在一个拥有这个属性的作用域中执行才有意义
注:在自定义指令中,处在模板的链接阶段时,指令会设置一个 $watch 函数来监听着作用域中各个表达式
$watch 允许指令在作用域中的属性变化时收到通知,进而让指令能够根据这个变化对 DOM 重新渲染,更新它改变的属性值
a、控制器 --> 作用域 --> 视图(DOM)
b、指令 --> 作用域 --> 视图(DOM)
控制器和指令是相互分离的,而且它们与视图之间也是分离的(耦合度低),可大大提高对应进行测试的工作效率
注:作用域的结构对应 DOM 结构,最顶层和 DOM 树的根节点一样,每个 Angular 应用有且仅有一个 root scope,子作用域可有多个
作用域对象与指令或控制器等 Angular 元素所在的 DOM 节点相关联 ==》 DOM 节点上可抓取到作用域这个对象