Angular 式的界面自动刷新具体是如何做到的?
除了 Angular, 还有 Reactive.js , 都是的 HTML 上实现的自动刷新功能, 简单说, 通过 DOM 操作对 DOM 进行更新, 相对 HTML 模板就节省了很多操作, 但具体是怎么做到的呢, 如何决定使用怎样的 DOM 操作呢?
Answers
建议楼主看一下 AngularJS 官网的这两篇介绍:
http://docs.angularjs.org/guide/compiler
http://docs.angularjs.org/guide/concepts
里面比较详细的介绍了它的执行过程
简单来说就是(真实情况下不完全是这样):
- AngularJS 解析整个模板,把每一个 DOM 节点调用了 $scope 中的哪些值记录下来
- 把 $scope 中的值,填充到 DOM 中引用了它的地方去;并且在 $scope 每次更新后,重新进行填充。
- 当用户与页面交互,更新了模板中的值的时候,把更新后的值写入 $scope
模板值更新后,把值同步到 $scope 里,这应该就是通过监听 DOM 事件来完成的,这个很好理解。
比较奇妙的是,$scope 的值更新后,它是怎么获知并同步到模板中去的。
我只是简单的 $scope.foo = 'bar' 而已,又没有调用什么函数通知它,它怎么就能知道我什么时候更新过 $scope 中的值呢?
我之前也一直疑惑这个问题,今天干脆好好研究了一下。于是看到了 AngularJS 的作者对此进行的解释:
http://stackoverflow.com/questions/9682092/databinding-in-angularjs/9693933#9693933
其实他用的是非常一个直白的方法:
就是每隔一段时间检查一下,看 $scope 中的值与以前记录的一不一样,如果不一样就说明它更新了,然后就调用相关的回调函数处理这次更新(例如:把新的值写进模板)。
循环往复,直到页面关闭。
这个功能是在 Scope.$digest 中实现的,可以在 AngularJS 源代码中搜索
"@name ng.$rootScope.Scope#$digest" 找到它的具体实现
这种实现方式牵扯到一个问题:性能
也正是因为这个原因,我之前一直认为这样一种实现方式不太可能。
反复不断的把所有的对象都挨个对照一遍,性能能行吗?
根据 AngularJS 作者的说法,没问题(实际使用中也没发现有什么问题,反倒比其他实现方式还快了呢)。
关键在于下面两点(翻译自作者的原文):
- 在什么情况下,用户才会觉得反应“慢”。实际上,人类的反应速度最快也就是50毫秒,只要界面元素的反应速度在50毫秒以内,对用户来说那就都是一瞬间的事。
- 在一个展示出来的界面下,最多能出现多少数据节点?我们几乎不可能在一个页面中展示2000个以上的数据节点,因为超出这个数值的话,用户就已经处理不了了。
所以真正的问题是:是不是能保证,即使在最慢的主流浏览器下,也能做到在50毫秒内完成2000次对象比较,也就是25微秒每次。这在今天,应该不成问题。
回答完毕
一不小心又写多了啊