Angular双向数据绑定原理之脏检查分析
来源:互联网 发布:2017淘宝企业开店流程 编辑:程序博客网 时间:2024/04/29 19:24
angular双向数据绑定原理
- 从UI到数据:UI事件,ajax请求,timeout等。
- 从数据到UI:脏检查
脏检查
1. 添加监听器$watcher
为scope中渲染在页面中的每个数据添加监听器$watcher,当添加$watcher
的数据发生变化时,调用所有watcher对应的listener,执行数据变化后的操作。
function $scope() { this.$$watchList = [];}$scope.prototype.$watch = function (name, getNewValue, listener) { var watch = { name: name,//scope中的数据名称 getNewValue: getNewValue,//数据的当前值 listener: listener || function () {} //数据变化时执行的操作 }; this.$$watchList.push(watch);};
2. 数据改变时调用所有watcher
中的listener
在$digest
里面调用所有watcher
。
$scope.prototype.$digest = function () { var list = this.$$watchList; for (var i = 0, l = list.length; i < l; i++) { var watch = list[i]; var newValue = watch.getNewValue(); var oldValue = watch.last;//第一次执行时oldValue为undefined if (newValue != oldValue) { watch.listener(newValue, oldValue); } watch.last = newValue; }};
此时当newValue != oldValue
时便执行$watcher对应的listener.
测试:
var scope = new $scope();scope.hello = 5;scope.$watch('hello', function () { return scope.hello; }, function (newValue, oldValue) { console.log('newValue: ' + newValue + ';oldValue:' + oldValue); });scope.$digest();scope.hello = 10;scope.$digest();scope.hello = 20;scope.$digest();scope.hello = 20;scope.$digest();scope.hello = 26;scope.$digest();newValue: 5;oldValue:undefinednewValue: 10;oldValue:5newValue: 20;oldValue:10newValue: 26;oldValue:20
3. 持续监听
然而当在另一个watcher
中改变其他watcher
中的值时,上面的digest
不能监听到变化:
var scope = new $scope();scope.hello = 5;scope.hello2 = 15;scope.$watch('hello', function () { return scope.hello; }, function (newValue, oldValue) { console.log('newValue: ' + newValue + ';oldValue:' + oldValue);});scope.$watch('hello2', function () { return scope.hello2; }, function (newValue, oldValue) { scope.hello = 10;//这里的改变并未检测到 console.log('newValue: ' + newValue + ';oldValue:' + oldValue);});scope.$digest();newValue: 5;oldValue:undefinednewValue: 15;oldValue:undefined
因此,在scope
中值发生变化时需要持续进行digest
,在digest
中设置所有数据是否为脏的标志dirty
,即每次执行digest
,若有数据发生变化,就将dirty
置为true
,若dirty
为true
继续执行digest
。
$scope.prototype.$$digestOnce = function () { var dirty; var list = this.$$watchList; for (var i = 0, l = list.length; i < l; i++) { var watch = list[i]; var newValue = watch.getNewValue(); var oldValue = watch.last; if (newValue !== oldValue) { watch.listener(newValue, oldValue); // 因为listener操作,已经检查过的数据可能变脏 dirty = true; } watch.last = newValue; } return dirty;};$scope.prototype.$digest = function () { var dirty = true; while (dirty) { dirty = this.$$digestOnce(); }};var scope = new $scope();scope.hello1 = 5;scope.hello2 = 10;scope.$watch('hello1', function () { return scope.hello1; }, function (newValue, oldValue) { console.log('newValue:' + newValue + '~~~~' + 'oldValue:' + oldValue); });scope.$watch('hello2', function () { return scope.hello2; }, function (newValue, oldValue) { scope.hello1 = 20;//这里的值被监听到 console.log('newValue:' + newValue + '~~~~' + 'oldValue:' + oldValue); });scope.$digest();newValue:5~~~~oldValue:undefinednewValue:10~~~~oldValue:undefinednewValue:20~~~~oldValue:5
4. 防止持续运行digest
陷入死循环
然而当在watcher
中互相改变对方的值,则会无限次digest
,此时陷入死循环,因此在,digest
中设置最多执行次数:
$scope.prototype.$digest = function() { var dirty = true; var checkTimes = 0; var maxTime = 10; while(dirty) { dirty = this.$$digestOnce(); checkTimes++; if(checkTimes > maxTime && dirty){ console.log("数据持续脏"); throw new Error("检测超过10次"); } }};
阅读全文
1 0
- Angular双向数据绑定原理之脏检查分析
- Angular双向数据绑定原理
- vue开发:vue,angular,react数据双向绑定原理分析
- angular 双向绑定原理
- Angular之双向数据绑定基础
- angular-数据双向绑定
- Angular双向数据绑定
- Angular双向数据绑定
- Angular双向数据绑定
- 双向绑定---angular之watch、apply、digest原理深入分析(源码分析)
- 单项数据绑定、双向数据绑定及其原理(脏检查)
- angular的双向绑定原理
- Vue双向数据绑定原理分析
- 【AngularJs】Angular双向数据绑定
- angular 的数据双向绑定
- angular数据双向绑定解密
- 双向数据绑定原理
- angular 双向绑定的实现原理
- mybatis generator逆向工程
- java 网络编程二 UDP传输协议(例:2个进程进行聊天)
- [HDU6118][2017"百度之星"程序设计大赛
- viewpager的布局
- English
- Angular双向数据绑定原理之脏检查分析
- 一键转载csdn博客
- Android Context的区别
- 三次握手
- Oil Deposits
- 使用Maven的方式搭建springmvc遇到pom.xml报错的问题
- $%7BpageContext.request.contextPath%7D
- Machine learning8-第一个非监督学习(聚类)
- 招聘面试的套路与原则