• AngularJS中的digest循环$apply


    欢迎大家指导与讨论 : )

      前言

      Angular会拓展这个标准的浏览器流程,创建一个Angular上下文。这个Angular上下文指的是运行在Angular事件循环内的特定代码,该Angular事件循环被称作为$digest循环。$digest循环有两个组成部分,分别是$watch列表和$evalAsync列表。

      例如,当 <input> 标签绑定了$scope.name属性,为了更新这个视图,Angular需要追踪变化。它是通过给$watch列表添加一个监控函数做到这一点。而$watch列表会在$digest循环中通过一个叫做"脏值检查"的程序解析。

      脏值检查

       Angular会持续追踪当前监控的值。Angular会遍历$watch列表,如果从旧值更新后的值没有发生变化,它会继续遍历监控列表。如果值发生了变化,则Angular会启用新值并继续遍历$watch列表。Angular会遍历完整个列表,只要有任何值发生变化,它就会退回到$watch循环中,直到检测到不再发生变化。如果这个循环运行了10次或者更多,则Angular会抛出一个异常,并停止运行。

      例子

      某间学校里,同学们都要在这儿住宿,但是呢有好几个学生很不乖,整天不好好睡觉,就知道玩游戏。学校领导知道后就要求老师说:"hey! 哥们, 这几间宿舍的学生特别不乖,你帮我多多看着他们!",同时把一份宿舍名单列表给了老师($watch列表里添加了监控函数)。每天晚上,老师都会不断巡查宿舍名单列表上的那几间宿舍(Angular遍历监控列表)。突然有一天,老师在巡查432宿舍的时候发现小明居然不好好睡觉而是在玩游戏!(Angular发现了变化),老师把小明教育了一顿,然后让它继续睡觉(启用变化后的新值)。但是老师就想,刚才小明是不是在和别的宿舍的同学一起联机玩游戏呢?我得继续巡查巡查(受变化值的影响,$watch列表中的其他值,可能跟随着一起发生了变化,也可能没有。例如$scope.num1=1,现在发生了变化,$scope.num1=10了。然后呢$scope.num2=2,不会受到$scope.num1影响,但是呢$scope.num3=num1+10的,它的值由原来的11变成了20, 因此Angular会进行二次巡查,直到监听的值没有再发生变化)。

      $watch

      $watch函数会给监听函数返回一个注销函数,我们可以通过调用注销函数来取消Angular对当前值的监听

    var unregisterWatch = $scope.watch('model.email', 
       function(newVal, oldVal){
           if(newVal === oldVal) return; //初始化
           if(newVal != oldVal){
                 //... 
           } 
       }   
    )

       假如对完成了该值的监听,可以通过调用 unregisterWatch() 来取消监控。其中,监听函数会在初始化时被调用一次,此时newVal === oldVal均为undefined

      $watchCollection

      可以通过此函数为对象的属性或者数组元素设置浅监控

    $scope.watchCollection('names', 
        function(newNames, oldNames){
         //
        }    
    )

      $apply()与$digest()

      $apply()函数可以从Angular框架的外部让表达式在Angular上下文内部执行,并让结果受控(进行digest循环)。例如实现了一个setTimeout()并想让事件运行在Angular上下文内部时,就必须使用$apply()

    $scope.apply(function(){
         setTimeout(function(){
             //...
         }, 1000)
    })

      或者直接通过调用$digest()函数进行digest循环,以进行脏值检查

    //..some action
    $scope.$digest();

      

     

      参考资料

      《AngularJS权威指南》P326

  • 相关阅读:
    java线程与并发(二)
    互联网金融时代的机遇和挑战
    SQL Server获取下一个编码字符串的实现方案分割和进位
    SQL Server获取下一个编码字符实现继续重构与增强
    SQL Server获取下一个编码字符实现
    SQL Server数字辅助表的实现
    SQL Server中中数据行批量插入脚本的存储实现
    SQL Server中的RAND函数的介绍和区间随机数值函数的实现
    SQL Server中字符串转化为GUID的标量函数实现
    SQL Server 中获取字符串拼音的标量函数实现
  • 原文地址:https://www.cnblogs.com/BestMePeng/p/AngularJS_Digest.html
Copyright © 2020-2023  润新知