一、浏览器下载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. Taxi

    /* After the lessons n groups of schoolchildren went outside and decided to visit Polycarpus to cele ...

  2. Oracle数据库mybatis 插入空值时报错(with JdbcType OTHER)

    参考文档: 1.https://blog.csdn.net/fishernemo/article/details/27649233 2.http://helgaxu.iteye.com/blog/21 ...

  3. .net委托

    今天要学的是委托 委托的基本形式 直接上代码 public delegate int AddDelegate(int x,int y); class Program { static void Mai ...

  4. [最新原创电子书]lazarus开发者入门及中级教程

    目前市面上没有任何一本完整的书,介绍Lazarus,Firebird这两个优秀的开发工具,同时还有一个作为他们之间桥梁的开发套件ZeosDBO,也没有任何完整的中文开发指南,本书以这三种开发套件为主线 ...

  5. [C#]this.Invoke和this.BeginInvoke的区别

    private void button1_Click(object sender, EventArgs e) { "; this.Invoke(new EventHandler(delega ...

  6. 海港(NOIP2016)

    题目链接:海港 这一题怎么样呢?还好吧,也不是太难,没有用到什么特殊的算法,但写法还是很值得学习的.下面讲一下思路: 我们维护三个队列(这里我们采用自己手写的队列,因为这比STL的要快,不过这一题,S ...

  7. 用python实现数学多元数学方程式计算

    题目:公鸡5元钱一只,母鸡3元钱一只,小鸡3只一块钱,其中公鸡,母鸡,小鸡都必须有,问公鸡,母鸡,小鸡各买多少只刚好凑足100元钱? 一:数学算术分析: x+y+z=100 5x+3y+z/3=100 ...

  8. 惊讶于word 的流畅

    word 这个产品 的操作流畅 比自家产品OneNote 比wps 强的太多 用后的体验是,再用其他的编译文字的软件,便感觉操作不畅,不流利,不舒服.(使人曾经沧海难为水,自然而然的不用别人的产品,w ...

  9. kbmmw 的HTTPSmartService入门

    前面介绍过kbmmw 中的smartservice. 这个既可以用于kbmmw 的客户端,也可以使用http 访问. 在新版的kbmmw里面,作者加强了http 的支持,我们可以只使用HTTPSmar ...

  10. 【转】Linux useradd

    Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统.用户的账号一方面可以帮助系统管理员对使用系统的用户进行 ...