一、浏览器下载HTML/CSS/JavaScript等

  当你转到一个页面地址后,浏览器先回下载这个HTML,同时,会开启一些辅助线程下载所关联的script标签和link标签里引用的文件。

二、浏览器构建DOM树

  下载的同时浏览器会开始构建DOM树,内嵌或引入的脚本也会开始执行,也就是说浏览器会逐个加载DOM树中的每一个元素节点,可以把AngularJS当做一个类似jQuery的js库,通过<script>标签引入到HTML中,此时Angular被作为一个普通的DOM节点等待浏览器解析,当浏览器解析到这个节点时,发现它是一个js文件,那么浏览器会停止解析剩余的DOM节点,开始执行这个js(即angular.js)。

三、jQuery初始化

  引用脚本中有一个是jQuery(如其不在AngularJS脚本之前引用,AngularJS就会启动其内置的jQLite),其启动代码会给自己挂接上document对象的DOMContentLoaded事件,通过调用jQuery.ready(callback)把一个回调函数注册到该事件中,后边DOM构建完毕时候,会触发该事件,并执行回调函数,会开始启动Angular,在触发之前,还有许多脚本要初始化,也就是DOM还未解析完成。

四、AngularJS初始化

  需要初始化的脚本中有另外一些AngularJS模块及其子模块,或一些第三方模块,此时会按引用顺序开始它们的初始化过程。模块的初始化过程大致相同:

  1、按名字创建模块,是一个对象,是其他Angular对象的注册表。

  2、在这个模块中注册各种Angular对象,如Controller、Service、Directive等,形成一个有名字和回调函数组成的对照表,这些回调函数现在还不会执行。

  3、模块中注册“config回调函数”和"run回调函数",分别在模块开始加载和加载结束时候执行,现在只是注册,不会执行。

五、jQuery启动

  当页面及其直接饮用的js文件都下载执行完后,DOM构建完成,浏览器会触发document对象的DOMContentLoaded事件,在jQuery.ready中注册的回调函数也会调用,其中代码会开启动AngularJS。

六、AngularJS启动

  此时,AngularJS正式登场,第一件事就是查找一个带有ng-app指令的节点,通常出现在body或html元素中,也可以出现在任意节点上,而且,一个页面可以有多个这样的节点;AngularJS找到第一个带有 ng-app节点,并调用angular.bootstrap(element,moduleName),element就是该节点,moduleName是该节点上指定的模块。

  AngularJS自启动方式,只会启动第一个ng-app的module;对于多个ng-app启动的方式,必须采用手动angular.bootstrap来启动。

  推荐,仅适用一个ng-app,然后,用Module和Controller来划分页面。

七、加载子模块

  AngularJS首先会创建一个注入器(injector),并关联到所在节点上,前边模块注册的一大堆Angular对象,都需要它才能被其他代码调用;接着,对当前节点的模块和所依赖模块进行初始化,顺序执行所有的"config回调函数";

  在config回调函数中能够使用的只有注册的常量(Constant)对象和Provider类,这里也是程序中唯一可以直接访问Provider类对服务进行配置的地方。

  比如,路由服务的Provider就是在这里初始化,但是,只是负责记录一个URL到“模板/控制器”组的映射表,供后边使用。

八、启动子模块

  模块加载完成后,会执行所有“run回调函数”,在这个阶段,各种Angular对象都可以使用了(如果想使用),包括各种Service、Factory等。

  接下来,控制权会转到路由模块,使用$location服务解析当前页面的URL,然后,根据这个URL查找响应的“模板/控制器”对(七、中生成的),来渲染一个页面。

九、渲染页面

  路由模块会先创建一个Scope对象,并加载模板,加载完毕后把它的内容传给$complie对象,其会先把它解析成一个静态DOM树,然后逐个扫描这棵DOM树种的指令,通过这些指令把Scope对象DOM树关联起来,包括渲染内容的函数和进行事件处理的函数。最后,用它替换一个特定指令所在的节点,即,ng-view/ui-view。

  $compile服务通过遍历DOM树的方式查找有声明指令的DOM元素。当碰到带有一个或多个指令的DOM元素时,它会排序这些指令(基于指令的priority优先级),然后使用$injector服务查找和收集指令的compile函数并执行它。每个节点的编译方法运行之后,$compile服务就会调用链接函数。

十、数据绑定和摘要循环

  此时,页面已经显示出来,但是数据还没有被渲染,AngularJS会自动使用Scope中的数据渲染一遍。

  通过”脏检查机制”,使得用户修改了数据,也能被渲染出来。

  它是一个称为“摘要循环”的过程,AngularJS会给每一个Scope成员变量求出一个 摘要值(能唯一标识一个变量),并保存在一个变量中,当调用Scope的$digest/$apply方法时候,会重新计算一遍摘要值,只要数据变化了,就会更新界面。

也就是说,Angular提供了自己的事件循环。指令自身会注册事件监听器,因此当事件被触发时,指令函数就会运行在AngularJS的$digest循环中。$digest循环会等待$watch表达式列表,当检测到模型变化后,就会调用$watch函数,然后再次查看$watch列表以确保没有

模型被改变。一旦摘要循环稳定下来,并且检测到没有潜在的变化了,执行过程就会离开Angular上下文并且会回到浏览器中,DOM将会被渲染到这里。

  注意:$digest不用直接调用,$apply是对它的封装,其也一般很少调用,因为在一些AngularJS事件指令以及$timeout等服务中,会自动调用它来确保界面刷新。

       自己挂接第三方组件的事件,就得记得手动调用一次$apply。

  到此,一个典型的AngularJS程序就启动成功了。

AngularJS 启动执行过程的更多相关文章

  1. 浅谈AngularJS启动引导过程

    我们都知道AngularJS默认会执行app.js来启动整个angular项目,但你知道angular具体执行过程吗? 一.自动引导启动框架 例如我们有如下代码,我们想要完成一个指令功能: <h ...

  2. 第8章7节《MonkeyRunner源代码剖析》MonkeyRunner启动执行过程-小结

    最后我们对MonkeyRunner启动的过程做一个总结,当然,当中也包括启动Monkey,尽管它不属于启动过程的一部分: monkeyrunner这个shell脚本会先设置一些执行环境的系统属性保存到 ...

  3. 第8章4节《MonkeyRunner源代码剖析》MonkeyRunner启动执行过程-启动AndroidDebugBridge

    上一节我们看到在启动AndroidDebugBridge的过程中会调用其start方法,而该方法会做2个基本的事情: 715行startAdb:开启AndroidDebugBridge 722-723 ...

  4. 第8章2节《MonkeyRunner源代码剖析》MonkeyRunner启动执行过程-解析处理命令行參数

    MonkeyRunnerStarter是MonkeyRunner启动时的入口类,由于它里面包括了main方法.它的整个启动过程主要做了以下几件事情: 解析用户启动MonkeyRunner时从命令行传输 ...

  5. 第8章5节《MonkeyRunner源代码剖析》MonkeyRunner启动执行过程-执行測试脚本

    MonkeyRunner在准备好AndroidDebugBridge和DeviceMonitor等服务之后,就基本上是攻克了和目标设备通信的问题了,那往下须要做的就是把測试脚本执行起来了. 178 p ...

  6. AngularJS应用的启动和执行过程

    启动(startup): <!doctype html> <html ng-app> <head> <script src="http://code ...

  7. AngularJS的启动引导过程

    原文:http://www.angularjs.cn/A137?utm_source=ourjs.com 目录: 引导之前 自动引导启动框架 手工引导启动框架 引导第1步:创建注入器 引导第2步:创建 ...

  8. AngularJS的加载执行过程

    1. HTML页面的加载,这会触发加载页面包含的所有JS (包括 AngularJS) 2. AngularJS启动,搜寻所有的指令(directive) 3. 找到ng-app,搜寻其指定的模块(M ...

  9. Angularjs启动入口, splash画面,与加快启动的技巧

    Angularjs启动入口, splash画面,与加快启动的技巧 Angularjs启动入口 * 自动响应DOMContentLoaded event * 从ngApp指定的入口启动: 在angula ...

随机推荐

  1. windows上安装RabbitMQ

    windows下 安装 rabbitMQ 及操作常用命令 rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 ...

  2. 用户态tcp协议栈调研

    一.各种用户态socket的对比 1.MTCP 简单介绍: 韩国高校的一个科研项目,在DPDK的2016年的技术开发者大会上有讲,所以intel将这个也放到了官方上,所以一般搜索DPDK的用户态的协议 ...

  3. MySQL学习笔记-MySQL体系结构总览

    MySQL体系结构总览 不管是用哪种数据库,了解数据库的体系结构都是极为重要的.MySQL体系结构主要由数据库和数据库实例构成. 数据库:物理操作系统文件或者其它文件的集合,在mysql中,数据库文件 ...

  4. qt 5.2.1类和模块的关系图

    QT│  ├─ActiveQt│  │  ActiveQt│  │  ActiveQtDepends│  │  ActiveQtVersion│  │  QAxAggregated│  │  QAxB ...

  5. Servlet开发的三种方法

    第一种 实现 Servlet 接口,需要覆写 Servlet 的5个方法,并将ServletConfig对象保存到类级变量中 package app01a; import java.io.IOExce ...

  6. [Robot Framework] Jenkins上调用Rebot命令时执行报错不往下执行其他命令

    在配置jenkins job时,添加构建步骤Execute Windows batch command,输入执行rebot命令 报错信息: Call C:\Python27\Scripts\rebot ...

  7. 【机器学习】用Octave实现一元线性回归的梯度下降算法

    Step1 Plotting the Data 在处理数据之前,我们通常要了解数据,对于这次的数据集合,我们可以通过离散的点来描绘它,在一个2D的平面里把它画出来. 6.1101,17.592 5.5 ...

  8. 【转】VxWorks中高精度实时时钟的实现及C语言汇编混合编程

    最近一个项目中需要在VxWorks下使用一个高精度实时时钟,要求精度为1ms,溢 出时间大于5小时.VxWorks提供系统时钟,该时钟在操作系统启动后开始计数,精度为1个tick,可以通过tickGe ...

  9. ssh安装

    http://blog.chinaunix.net/uid-20791108-id-3761681.htmlhttp://www.cnblogs.com/mliudong/p/4094519.html ...

  10. syslog系统日志、Windows事件日志监控