一、浏览器下载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. C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)

      BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段 : ...

  2. OpenSource.SerializationLibrary

    1. Cap'n Proto protocol buffer的主要作者之一创建的新项目.其主页描述Cap'n Proto的性能比PB快很多. http://kentonv.github.io/capn ...

  3. iOS8 UIAlertView键盘闪一下的问题

    if (SYSTEM_VERSION >= 8.0) { UIAlertController *alertCtrl = [UIAlertController alertControllerWit ...

  4. 看起来像是PS的照片,实际上却令人难以置信!

    图片来源:网络 在现实生活中 很多照片看起来不可思议 就像经过PS处理的一样. 今天就跟随米醋一起来感受一下 看这些超现实的真实照片. 一张感光过度的照片, 让狗的头看起来像是悬浮的. 一只被困在琥珀 ...

  5. Nginx+Tomcat安装与配置(windows版)

    相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人未必了解. 说到反向代理,可能很多人都听说,但具体什么是反向代理,很多人估计就不清楚了 ...

  6. 用visual studio 2017来调试python

    https://www.visualstudio.com/zh-hans/thank-you-downloading-visual-studio/?sku=Professional&rel=1 ...

  7. 2017/2/6:在oracle中varchar与varchar2的区别与增删改查

    1.varchar2把所有字符都占两字节处理(一般情况下),varchar只对汉字和全角等字符占两字节,数字,英文字符等都是一个字节:2.VARCHAR2把空串等同于null处理,而varchar仍按 ...

  8. 再读c++primer plus 001

    1. OOP强调的是在运行阶段(而不是编译阶段)进行决策,运行阶段指的是程序正在运行时,编译阶段指的是编译器将程序组合起来时. 2.变量的值都存储在栈中,而new从被称为堆或自由存储区的内存区域分配内 ...

  9. keras环境

    Windows 7 python3.6 在安装 Keras 之前, 需要确认自己已经安装好了 Numpy 和 Scipy. 安装个anaconda3就可以搞定 因为 Keras 是基于 Tensorf ...

  10. 2018.11.06 bzoj1040: [ZJOI2008]骑士(树形dp)

    传送门 由题可知给出的是基环森林. 因此对于每个基环森林找到环断开dpdpdp两次就行了. 代码: #include<bits/stdc++.h> using namespace std; ...