自得怡乐 發表於 2020-11-4 09:32:00

Angular的工作原理

<p>来源:https://www.cnblogs.com/moriah/p/6096998.html</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;!</span><span style="color: rgba(255, 0, 255, 1)">doctype html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">html </span><span style="color: rgba(255, 0, 0, 1)">ng-app</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="angular.js"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">png-init</span><span style="color: rgba(0, 0, 255, 1)">=" name='World' "</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Hello {{name}}!<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>&nbsp; &nbsp; &nbsp;当你用浏览器去访问index.html的时候,浏览器依次做了如下一些事情:</p>
<ol>
<li>加载html,然后解析成DOM;</li>
<li>加载angular.js脚本;</li>
<li>AngularJS等待DOMContentLoaded事件的触发;</li>
<li>AngularJS寻找ng-app指令,根据这个指令确定应用程序的边界;</li>
<li>使用ng-app中指定的模块配置$injector;</li>
<li>使用$injector创建$compile服务和$rootScope;</li>
<li>使用$compile服务编译DOM并把它链接到$rootScope上;</li>
<li>ng-init指令对scope里面的变量name进行赋值;</li>
<li>对表达式{{name}}进行替换,于是乎,显示为“Hello World!”&nbsp; &nbsp; &nbsp;</li>
</ol>
<p>  整个过程可以用这张图来表示:</p>
<p><img src="https://img2020.cnblogs.com/blog/2148836/202011/2148836-20201104091657035-1324484238.png"></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;好了,通过上面的例子我们清楚了AngularJS是怎样一步一步渲染出一个页面的。那么它又是如何和浏览器的事件回路来交互的呢?或者说是如何跟用户来交互的呢?粗略来讲,主要分为三个阶段:<br>  1. &nbsp;浏览器的事件回路一直等待着事件的触发,事件包括用户的交互操作、定时事件或者网络事件(如服务器的响应等);<br>  2. &nbsp;一旦有事件触发,就会进入到Javascript的context中,一般通过回调函数来修改DOM;<br>  3. &nbsp;等到回调函数执行完毕之后,浏览器又根据新的DOM来渲染新的页面。<br>&nbsp; &nbsp; &nbsp;正如下面一张图所示,交互过程主要由几个循环组成:</p>
<p><img src="https://img2020.cnblogs.com/blog/2148836/202011/2148836-20201104091910583-1445384097.png"></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;AngularJS修改了一般的Javascript工作流,并且提供了它自己的事件处理机制。这样就把Javascript的context分隔成两部分,一部分是原生的Javascript的context,另一部分是AngularJS的context。只有处在AngularJS的context中的操作才能享受到Angular的data-binding、exception handling、property watching等服务,但是对于外来者(如原生的Javascript操作、自定义的事件回调、第三方的库等)Angular也不是一概不接见,可以使用AngularJS提供的$apply()函数将这些外来者包进AngularJS的context中,让Angular感知到他们产生的变化。</p>
<p>&nbsp; &nbsp; &nbsp;接下来,让我们一起来看看交互过程中的这几个循环是怎么工作的?<br>  1. &nbsp;首先,浏览器会一直处于监听状态,一旦有事件被触发,就会被加到一个event queue中,event queue中的事件会一个一个的执行。<br>  2. &nbsp;event queue中的事件如果是被$apply()包起来的话,就会进入到AngularJS的context中,这里的fn()是我们希望在AngularJS的context中执行的函数。<br>  3. &nbsp;AngularJS将执行fn()函数,通常情况下,这个函数会改变应用的某些状态。<br>  4. &nbsp;然后AngularJS会进入到由两个小循环组成的$digest循环中,一个循环是用来处理$evalAsync队列(用来schedule一些需要在渲染视图之前处理的操作,通常通过setTimeout(0)实现,速度会比较慢,可能会出现视图抖动的问题)的,一个循环是处理$watch列表(是一些表达式的集合,一旦有改变发生,那么$watch函数就会被调用)的。$digest循环会一直迭代知道$evalAsync队列为空并且$watch列表也为空的时候,即model不再有任何变化。<br>  5. &nbsp;一旦AngularJS的$digest循环结束,整个执行就会离开AngularJS和Javascript的context,紧接着浏览器就会把数据改变后的视图重新渲染出来。<br><br>&nbsp; &nbsp; &nbsp;接下来,我们还是结合代码来解析一下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;!</span><span style="color: rgba(255, 0, 255, 1)">doctype html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">html </span><span style="color: rgba(255, 0, 0, 1)">ng-app</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="angular.js"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">ng-model</span><span style="color: rgba(0, 0, 255, 1)">="name"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Hello {{name}}!<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>&nbsp; &nbsp; &nbsp;这段代码和上一段代码唯一的区别就是有了一个input来接收用户的输入。在用浏览器去访问这个html文件的时候,input上的ng-model指令会给input绑上keydown事件,并且会给name变量建立一个$watch来接收变量值改变的通知。在交互阶段主要会发生以下一系列事件:<br>  1. &nbsp;当用户按下键盘上的某一个键的时候(比如说A),触发input上的keydown事件;<br>  2. &nbsp;input上的指令察觉到input里值的变化,调用$apply(“name=‘A’”)更新处于AngularJS的context中的model;<br>  3. &nbsp;AngularJS将’A’赋值给name;<br>  4. &nbsp;$digest循环开始,$watch列表检测到name值的变化,然后通知{{name}}表达式,更新DOM;<br>  5. &nbsp;退出AngularJS的context,然后退出Javascript的context中的keydown事件;<br>  6. &nbsp;浏览器重新渲染视图。</p><br><br>
来源:https://www.cnblogs.com/yanjianjiang/p/13924252.html
頁: [1]
查看完整版本: Angular的工作原理