Angular 式的界面自动刷新具体是如何做到的?


除了 Angular, 还有 Reactive.js , 都是的 HTML 上实现的自动刷新功能, 简单说, 通过 DOM 操作对 DOM 进行更新, 相对 HTML 模板就节省了很多操作, 但具体是怎么做到的呢, 如何决定使用怎样的 DOM 操作呢?

web前端开发 angularjs JavaScript

已有该昵称 10 years, 11 months ago

建议楼主看一下 AngularJS 官网的这两篇介绍:
http://docs.angularjs.org/guide/compiler
http://docs.angularjs.org/guide/concepts
里面比较详细的介绍了它的执行过程

简单来说就是(真实情况下不完全是这样):

  1. AngularJS 解析整个模板,把每一个 DOM 节点调用了 $scope 中的哪些值记录下来
  2. 把 $scope 中的值,填充到 DOM 中引用了它的地方去;并且在 $scope 每次更新后,重新进行填充。
  3. 当用户与页面交互,更新了模板中的值的时候,把更新后的值写入 $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 作者的说法,没问题(实际使用中也没发现有什么问题,反倒比其他实现方式还快了呢)。
关键在于下面两点(翻译自作者的原文):

  1. 在什么情况下,用户才会觉得反应“慢”。实际上,人类的反应速度最快也就是50毫秒,只要界面元素的反应速度在50毫秒以内,对用户来说那就都是一瞬间的事。
  2. 在一个展示出来的界面下,最多能出现多少数据节点?我们几乎不可能在一个页面中展示2000个以上的数据节点,因为超出这个数值的话,用户就已经处理不了了。

所以真正的问题是:是不是能保证,即使在最慢的主流浏览器下,也能做到在50毫秒内完成2000次对象比较,也就是25微秒每次。这在今天,应该不成问题。

回答完毕


一不小心又写多了啊

卡巴兔斯基 answered 10 years, 11 months ago

Your Answer