AngularJS实现原理
个人觉得,要很好的理解AngularJS的运行机制,才能尽可能避免掉到坑里面去。在这篇文章中,我将根据网上的资料和自己的理解对AngularJS的在启动后,每一步都做了些什么,做一个比较清楚详细的解析。
首先上一小段代码(index.html),结合代码我们来看看,angular一步一步都做了些什么。
<!doctype html>
<html ng-app>
<head>
<script src="angular.js"></script>
</head>
<body>
<png-init=" name='World' ">Hello {{name}}!</p>
</body>
</html>
当你用浏览器去访问index.html的时候,浏览器依次做了如下一些事情:
- 加载html,然后解析成DOM;
- 加载angular.js脚本;
- AngularJS等待DOMContentLoaded事件的触发;
- AngularJS寻找ng-app指令,根据这个指令确定应用程序的边界;
- 使用ng-app中指定的模块配置$injector;
- 使用injector创建injector创建 compile服务和$rootScope;
- 使用compile服务编译DOM并把它链接到compile服务编译DOM并把它链接到 rootScope上;
- ng-init指令对scope里面的变量name进行赋值;
- 对表达式{{name}}进行替换,于是乎,显示为“Hello World!”
整个过程可以用这张图来表示:
好了,通过上面的例子我们清楚了AngularJS是怎样一步一步渲染出一个页面的。那么它又是如何和浏览器的事件回路来交互的呢?或者说是如何跟用户来交互的呢?粗略来讲,主要分为三个阶段:
1. 浏览器的事件回路一直等待着事件的触发,事件包括用户的交互操作、定时事件或者网络事件(如服务器的响应等);
2. 一旦有事件触发,就会进入到Javascript的context中,一般通过回调函数来修改DOM;
3. 等到回调函数执行完毕之后,浏览器又根据新的DOM来渲染新的页面。
正如下面一张图所示,交互过程主要由几个循环组成:
AngularJS修改了一般的Javascript工作流,并且提供了它自己的事件处理机制。这样就把Javascript的context分隔成两部分,一部分是原生的Javascript的context,另一部分是AngularJS的context。只有处在AngularJS的context中的操作才能享受到Angular的data-binding、exception handling、property watching等服务,但是对于外来者(如原生的Javascript操作、自定义的事件回调、第三方的库等)Angular也不是一概不接见,可以使用AngularJS提供的$apply()函数将这些外来者包进AngularJS的context中,让Angular感知到他们产生的变化。
接下来,让我们一起来看看交互过程中的这几个循环是怎么工作的?
1. 首先,浏览器会一直处于监听状态,一旦有事件被触发,就会被加到一个event queue中,event queue中的事件会一个一个的执行。
2. event queue中的事件如果是被$apply()包起来的话,就会进入到AngularJS的context中,这里的fn()是我们希望在AngularJS的context中执行的函数。
3. AngularJS将执行fn()函数,通常情况下,这个函数会改变应用的某些状态。
4. 然后AngularJS会进入到由两个小循环组成的digest循环中,一个循环是用来处理digest循环中,一个循环是用来处理 evalAsync队列(用来schedule一些需要在渲染视图之前处理的操作,通常通过setTimeout(0)实现,速度会比较慢,可能会出现视图抖动的问题)的,一个循环是处理watch列表(是一些表达式的集合,一旦有改变发生,那么watch列表(是一些表达式的集合,一旦有改变发生,那么 watch函数就会被调用)的。digest循环会一直迭代知道digest循环会一直迭代知道 evalAsync队列为空并且$watch列表也为空的时候,即model不再有任何变化。
5. 一旦AngularJS的$digest循环结束,整个执行就会离开AngularJS和Javascript的context,紧接着浏览器就会把数据改变后的视图重新渲染出来。
接下来,我们还是结合代码来解析一下:
<!doctype html>
<html ng-app>
<head>
<script src="angular.js"></script>
</head>
<body>
<input ng-model="name">
<p>Hello {{name}}!</p>
</body>
</html>
这段代码和上一段代码唯一的区别就是有了一个input来接收用户的输入。在用浏览器去访问这个html文件的时候,input上的ng-model指令会给input绑上keydown事件,并且会给name变量建议一个$watch来接收变量值改变的通知。在交互阶段主要会发生以下一系列事件:
1. 当用户按下键盘上的某一个键的时候(比如说A),触发input上的keydown事件;
2. input上的指令察觉到input里值的变化,调用$apply(“name=‘A’”)更新处于AngularJS的context中的model;
3. AngularJS将’A’赋值给name;
4. digest循环开始,digest循环开始, watch列表检测到name值的变化,然后通知{{name}}表达式,更新DOM;
5. 退出AngularJS的context,然后退出Javascript的context中的keydown事件;
6. 浏览器重新渲染视图。
最后,希望这篇博客能帮助大家更好的理解AngularJS在背后干的事情。如有不确切的地方,请指正!
转自http://www.cnblogs.com/penghongwei/p/3444601.html
AngularJS实现原理的更多相关文章
- angularJS核心原理
一.angularJS优点和缺点 优点 1.1免去重复劳动-获取元素.给元素加事件.创建元素 1.2接管UI:angularJS根据数据创建UI元素,免去手工创建UI元素. 1.3自动同步:根据数据个 ...
- angularjs工作原理解析
个人觉得,要很好的理解AngularJS的运行机制,才能尽可能避免掉到坑里面去.在这篇文章中,我将根据网上的资料和自己的理解对AngularJS的在启动后,每一步都做了些什么,做一个比较清楚详细的解析 ...
- AngularJs数据绑定原理
注 这篇博文主要是写给新手的,是给那些刚刚开始接触Angular,并且想了解数据帮定是如何工作的人.如果你已经对Angular比较了解了,那强烈建议你直接去阅读源代码. Angular用户都想知道数据 ...
- [渣翻译] 在ASP.NET MVC WebAPI项目中使用 AngularJS
原文地址http://blog.technovert.com/2013/12/setting-up-angularjs-for-asp-net-mvc-n-webapi-project/ 我们最近发布 ...
- 【总结】AngularJs学习总结
应项目的需要,一个月之前开始做WebComponents.Javascript MVC框架的技术调研,由于重点是想做组件化,所以就没有考虑Backbone(去年就小试牛刀,太难用了)及其他的mvc框架 ...
- 常用前端框架Angular和React的一些认识
为什么要用AngularJs? 要了解为什么使用AngularJS首先就要接受它的思想: 首先,angularJS借助了传统MVC的架构模式(model模型 view视图 controller控制 ...
- AngularJS实现单页应用的原理——路由(Route)
AngularJS实现单页应用的原理——路由(Route) 路由:告诉你一个通往某个特定页面的途径 http://127.0.0.1/index.html#/start http://127.0.0. ...
- AngularJS的工作原理1
AngularJS的工作原理 个人觉得,要很好的理解AngularJS的运行机制,才能尽可能避免掉到坑里面去.在这篇文章中,我将根据网上的资料和自己的理解对AngularJS的在启动后,每一步都做了些 ...
- AngularJS的工作原理
AngularJS的工作原理 个人觉得,要很好的理解AngularJS的运行机制,才能尽可能避免掉到坑里面去.在这篇文章中,我将根据网上的资料和自己的理解对AngularJS的在启动后,每一步都做了些 ...
随机推荐
- 一次http请求响应流程
前端客户端 发起http请求 web服务器接收并解析http报文 通过WSGI协议发送给web框架 web框架创建请求对象 中间层处理 具体的视图处理-业务处理 中间层处理 创建http响应对象 返回 ...
- SyntaxError: Non-UTF-8 code starting with '\xb6' in file XX.py
导致出错的根源就是编码问题. 解决方案是: 在程序最上面加上: # coding=gbk
- 123th LeetCode Weekly Contest Broken Calculator
On a broken calculator that has a number showing on its display, we can perform two operations: Doub ...
- BZOJ - 3295 三维偏序 空间转换
题意:动态逆序对,共m次删除操作,求每次操作前的逆序对个数 删除操作转换为添加操作,首先对时间a进行简单排序 然后用cdq分治处理b维,树状数组处理c维 此时需要求的是对于某有序组\((a,b,c)\ ...
- kamctl start
尽管没有吃饭,胃酸,九点半,,,还是挺高兴的.只截图不说话. 这个问题弄得我好烦啊.几个小时...网罗了国外几个论坛都没有解.我还没有想到这就不是问题,,,多试多试 再看看moni 也没什么意思,就是 ...
- css提取数据2个常用方法
提取标签里的内容 所谓数据就是HTML里标签的内容,如下面红色字体,就是标签内容 <title>我只是个实验 - SCRAPY</title> 提取标签里的数据,标签可以是ti ...
- CAN2.0A帧格式 与 LIN帧格式 简单说明
一.标准的2.0A帧格式 各字段解释:SOF帧开始标志比特是一个显性比特(0),由一个或多个准备发送帧的节点传输.SOF标志着帧的开始(或仲裁发送帧的权利),并用于“硬同步”总线上的设备.只有在开始发 ...
- android 捕获未try的异常
1.Thread.UncaughtExceptionHandler java里有很多异常如:空指针异常,越界异常,数值转换异常,除0异常,数据库异常等等.如果自己没有try / catch 那么线程就 ...
- 10g 升级到11g 失效对象2则
########SAMPLE 0 Invalid X_$ Views & Synonyms After Upgrading to 11g (文档 ID 878623.1) Those view ...
- atoi和stoi
vs环境下:stoi函数默认要求输入的参数字符串是符合int范围的[-2147483648, 2147483647],否则会runtime error.atoi函数则不做范围检查,若超过int范围,则 ...