自动引导
AngularJs 通过 ng-app 指令进行自动引导
手工引导启动框架
如果一个HTML文件中 有多个ng-app,AngularJS只会自动引导启动它找到的第一个ng-app应用,这是需要手工引导 的一个应用场景。
我们可以利用angular.bootstrap()方法进行手动引导:
angular.bootstrap(element, [modules], [config]);
bootstrap方法有三个参数:
- element : 一个DOM元素,以这个元素为Angular应用的根,等同自动引导时ng-app所在 的元素。这个参数是必须的。比如:document、document.body等。
- modules : 引导时需要载入的模块数组。比如:[]、["test"]等。由于我们的HTML中引用 了test模块中定义的hello指令,所以,我们需要指定载入test模块。
- config :引导配置项,可选。我们先忽略。
最终,我们使用如下的形式进行手动引导:
angular.bootstrap(document,["test"]);
引导步骤
1. 创建注入器
无论自动启动还是手工启动,最终都是调用angular对象上的injector()方法创建了一个 注入器,然后把这个注入器存入了根对象的data里:
1 var injector = angular.injector(["ng","ezstuff"]);2 angular.element(document).data("$injector",injector);
2. 创建根作用域
scope对象是AngularJS实现数据绑定的重要服务,所以,在引导启动建立了注入器之后, AngularJS马上在应用的根节点上创建一个根作用域:$rootScope对象。
自动引导启动:ng-app所在的DOM节点对应着根作用域。
手工引导启动:在bootstrap方法中指定的第一个参数就对应着根作用域。
一旦$rootScope对象创建成功,AngularJS就将这个对象存储到根节点 的data中,我们可以使用如下的方法查看这个对象:
angular.element(approot).data("$rootScope");
3. 编译DOM子树
编译过程通常借助于指令,完成这几种操作:
•对DOM对象进行变换。
•在DOM对象上挂接事件监听。
•在DOM对象对应的scope对象上挂接数据监听。
代码:
//模拟引导启动过程angular.element(document).ready(function(){ //第一步:创建注入器并保存到根对象的data中 var injector = angular.injector(["ng","test"]); angular.element(document).data("$injector",injector); //第二步:创建根作用域并保存到根对象的data中 var rootScope = injector.get("$rootScope"); angular.element(document).data("$rootScope",rootScope); //第三步:编译DOM树 var compile = injector.get("$compile") compile(document)(rootScope);});angular.module("test",[]).directive("hello",function(){ return { restrict : "E", template : "" };});
编译器/$compile
编译器$compile是一个AngularJS的内置服务,它负责遍历DOM树来查找匹配指令, 并调用指令的实现代码进行处理。
HTML编译包括3个步骤:
•匹配指令
$compile遍历DOM树,如果发现有元素匹配了某个指令,那么这个指令将被加入 该DOM元素的指令列表中。一个DOM元素可能匹配多个指令。
•执行指令的编译函数
当一个DOM元素的所有指令都找齐后,编译器根据指令的优先级/priority指令进行排序。 每个指令的compile函数被依次执行。每个compile执行的结果产生一个link函数,这些 link函数合并成一个复合link函数。
•执行生成的链接函数
$compile通过执行指令的link函数,将模板和scope链接起来。结果就是一个DOM视图和scope对象模型 之间的动态数据绑定。
指令/directive
笼统地说,指令是DOM元素(例如属性、元素、CSS类等)上的标记符,用来告诉AngularJS的HTML编译器 ($compile服务)将特定的行为绑定到DOM元素,或者改变DOM元素
如np-bind指令
1 2 34
指令的实现本质上就是一个类工厂,它返回一个指令定义对象,编译器根据这个指令定义对象进行操作。
如何匹配指令?
AngularJS在进行匹配检测之前,首先对HTML元素的标签和属性名转化成规范的驼峰式字符串:
•去除名称前缀的x-和data-
•以: , - 或 _ 为分割符,将字符串切分成单词,除第一个单词外,其余单词首字母大写
•重新拼接各单词