脏检查是AngularJS的核心机制之一,它是实现双向绑定、MVVM模式的重要基础。

一、digest循环

  AngularJS将双向绑定转换为一个堆watch表达式,然后递归检查这些watch表达式的结果有没有变化,如果变了,就会执行响应的watcher函数,等到model值不再变化,也就不会再有watcher函数被触发。

  此时,浏览器会重新渲染DOM来体现model的改变,这里所说的watcher函数,是有view上的指令,如ngBind、ngShow、ngHide,或{{}}表达式所注册,它其实是指令在AngularJS的complie阶段会逐一解析、注册。

  AngularJS并不是周期性触发脏检查。只有当view中事件,ajax请求或者 timeout 延迟事件,才会触发脏检查。$scope.$apply是触发脏检查机制的公开接口。我们在封装第三方jQuery插件时,不能自动更新View,需要手动调用$scope.$apply。

二、$watch 对象  

  Angular 每一个绑定到view上的数据,就会有一个 $watch 对象,每当我们将数据绑定到 view上,AngularJS 就会向你的 watchList 上插入一个 $watch对象。这个对象包含三个参数

watch = {
name:'', //当前的watch 对象 观测的数据名
getNewValue:function($scope){ //得到新值
...
return newValue;
},
listener:function(newValue,oldValue){ // 当数据发生改变时需要执行的操作
...
}
}

  getNewValue() 可以得到当前$scope 上的最新值,listener 函数得到新值和旧值并进行一些操作。而常常我们在使用AngularJS的时候,listener 一般都为空,只有当我们需要监测更改事件的时候,才会显示地添加监听。

三、双向数据绑定

  AngularJS实现了双向数据绑定,就是view中的操作能实时反应到viewModel数据,viewModel数据的更改也能在View呈现。view到viewModel数据的更改,是由 vew中绑定的事件,ajax请求,或者tmeout 等回调操作完成,而viewModel数据到view的更新呈现则是由脏检查来做。只有当触发view中的事件,ajax请求或者 timeout 延迟,才会触发脏检查,如用户在文本框里输入了数据,或者ajax取回的新的数据要应用在程序中,或者用户点击了东西需要我们更改一些数据。如果直接使用DOM的onclick方法,数据虽然变更了,但是还没有往View上填充,我们需要在此做一些附加操作。

  双向绑定机制,在DOM操作中,虽然更新了数据的值,但是并没有立即反映到View上,而是通过 apply() 来反映到view上。AngularJS的ng-click 封装了click,然后调用一次 apply 函数,把数据呈现到界面上。在AngularJS 的apply函数中,先进行脏检测,检测 oldValue 和 newVlue 是否相等,如果不相等,将newValue 反馈到界面上,如果通过 $watch 注册了 listener事件,那么就会调用该事件。

四、过程描述

  当接收View上的指令所转发的事件时,就会切换到AngularJS的上下文环境来响应这类事件,digest循环就会触发;遍历一遍所有watcher函数(表达式或对象)称为一轮脏检查,执行完一轮检查,若任一watcher所监听的值改变过,那就重新再进行一次脏检查,知道所有watcher所监听的值都没有变化。

  从第一轮脏检查到结果变得稳定,这是一次digest循环完整过程,当循环结束后,才把变化更新到DOM去,这样可以合并多个更新,防止频繁的DOM操作。

AngularJS 脏检查机制的更多相关文章

  1. 手写AngularJS脏检查机制

    什么是脏检查 View -> Model 浏览器提供有User Event触发事件的API,例如,click,change等 Model -> View 浏览器没有数据监测API. Ang ...

  2. angularjs脏检查

    angularjs实现了双向绑定,与vue的defineProperty不同,它的原理在于它的脏检查机制,以下做了一些总结: angular.js介绍 AngularJs是mvvm框架,它的组件是vm ...

  3. AngularJS 脏检查深入分析

    写在开头 关于Angular脏检查,之前没有仔细学习,只是旁听道说,Angular 会定时的进行周期性数据检查,将前台和后台数据进行比较,所以非常损耗性能. 这是大错而特错的.我甚至在新浪前端面试的时 ...

  4. angular何时触发脏检查机制

    ng只有在指定事件触发后,才进入$digest cycle: DOM事件,譬如用户输入文本,点击按钮等.(ng-click) XHR响应事件 ($http) 浏览器Location变更事件 ($loc ...

  5. angular2 脏检查机制

    https://www.waitig.com/angular2-%E8%84%8F%E6%A3%80%E6%9F%A5%E8%BF%87%E7%A8%8B.html https://zhuanlan. ...

  6. AngularJs 脏值检查及其相关

    今天突然就想写写$digest和$apply,这些都是脏值检查的主体内容. 先以普通js来做一个简单的监控例子吧: var div = ducoment.getElementById("my ...

  7. Hibernate[延迟加载] [三种状态] [脏检查] [缓存机制]

    一.持久化对象的唯一标识 java中按内存地址不同区分同一个类的不同对象,关系数据库用主键区分同一条记录,Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系 什么是OID? 解析: ...

  8. java对象中的三种状态和脏检查及刷新缓存机制

    瞬时状态 瞬时状态又称临时状态.如果java对象与数据库中的数据没有任何的关联,即此java对象在数据库中没有相关联的记录,此时java对象的状态为瞬时状态,session对于 瞬时状态的ava对象是 ...

  9. angularjs脏机制

    Angular 每一个绑定到UI的数据,就会有一个 $watch 对象. watch = { name:'', //当前的watch 对象 观测的数据名 getNewValue:function($s ...

随机推荐

  1. BPF+XDP比较全的资料都在这里

    Dive into BPF: a list of reading material Sep 1, 2016 • Quentin Monnet◀Table of contents What is BPF ...

  2. 多字节字符集与Unicode字符集

    在计算机中字符通常并不是保存为图像,每个字符都是使用一个编码来表示的,而每个字符究竟使用哪个编码代表,要取决于使用哪个字符集(charset). 多字节字符集: 在最初的时候,Internet上只有一 ...

  3. 一个漂亮的lazarus做的pagecontrol

    厌倦了屏幕上的默认灰色?让我们来欣赏一下商业配色. 这个组件实现了高光,点睛色,描边边等效果, 再配几组色彩,应该非常不错. 基于 lazarus 1.08 大家可以上 www.fpccn.com 看 ...

  4. netstat 查看端口命令

    查看特定端口是否启动 netstat -lnp |

  5. Python之路(第二十五篇) 面向对象初级:反射、内置方法

    [TOC] 一.反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它 ...

  6. android 使用webview 加载网页

    1. <WebView android:id="@+id/webView" android:layout_width="fill_parent" andr ...

  7. Python参数类型

    位置参数 默认参数 可变参数 命名关键字参数 关键字参数 def position_only(a, b): print(a, b) def keyword(a='a', b='b'): print(a ...

  8. ubunut下安装ibus_pinyin中文输入法

    ubuntu安装中文输入法,,此处一ibus-pinyin为例为其安装中文输入法,,, 1. 设置(setting)---语言支持(language support)---汉语(chinese),,, ...

  9. python递归和二分法

    一.递归 1.递归就是自己调用自己 def fn(n): print(n) fn(n+1) fn(1) #递归深度官方1000 一般都递归到998 2.树形结构的遍历 import os def fn ...

  10. 783. Minimum Distance Between BST Node

    方法一,非递归方法,中序遍历 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *l ...