>  Q&A  >  본문

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

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

阿神阿神2748일 전552

모든 응답(2)나는 대답할 것이다

  • PHP中文网

    PHP中文网2017-04-10 12:50:53

    建议楼主看一下 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微秒每次。这在今天,应该不成问题。

    回答完毕


    一不小心又写多了啊

    회신하다
    0
  • 怪我咯

    怪我咯2017-04-10 12:50:53

    说白了就是事件监听。

    假设DOM为一个input元素,Model是一个对象person的属性name,那么从DOM到数据这个绑定我想你应该很清楚: 监听input元素相关事件(这里可能为onchange),捕捉到事件后更新数据模型,比如:

    input.onchange=function(){
      person.name=input.value;
    }
    

    反过来,对象的属性变化也是可以监听的,就可以实现从Model到DOM的更新:

    person.addListener("name_change",function(){
      input.value=person.name;
    });
    

    例子中的代码只是为了说明,实际情况中要比这个考虑更多内容。

    HTH

    회신하다
    0
  • 취소회신하다