• angular1.x 脏检测


    写在前面

      双向绑定是angular的大亮点,然后支撑它的就是脏检测。一直对脏检测都有一些理解,却没有比较系统的概念。

      以下是我阅读网上博文以及angular高级程序设计的理解与总结。

      接收指导与批评。

    脏检查:

      将原对象赋值一份快照。在某个时间,遍历比较这个对象和快照(新旧值),如果不一样就执行执行某些操作。

    angular中的脏检查:

      1.不会检查所有的对象。当对象被绑定到html会检查,手动$scope.$watch()的会检查。检查的手段就是为这些对象创建(watcher)对象。并push到(watcher队列) 2.不会检查所有的属性。只要被绑定的属性才会被注册。 在angular程序初始化时,会将绑定的对象的属性添加为监听对象(watcher),也就是说一个对象绑定了N个属性,就会添加N个watcher。

    angular注册watcher对象

      angualr会为每一个绑定到DOM的对象/对象的属性,创建一个watcher对象,(使用$scope.$watch()方法也会创建),watcher对象有好几个属性,(下面是笔者理解抽象出来的,并不是真的属性名

    watch = {
      name:'',      //当前的watch 对象 观测的数据名,锁定监听的是什么
      getNewValue:function($scope){ //获取监听属性的最新值
          ...
          return newValue;
          },
      listener:function(newValue,oldValue){  // 先比较新值与旧值判断是否继续执行,一般负责使用新值更新DOM页面,也可以是$watch方法注册的回调函数
          ...
      }
    }

      $$watchers的watcher属性截图

    $scope.$$watchers队列

      每一个创建好的watcher对象会被push到各自的controller作用域的$scope.$$watchers队列里面。
      脏检测就是遍历watchers的过程。


    脏检测通过两个方法触发:$digest(), $apply()
      $digest:是遍历当前作用域以及其子作用域的$$watchers队列,并执行其listener。
      $apply:是对$digest()的封装。接受一个函数参数(包含脱离angular环境的逻辑,需要却不会自己触发脏检测, 所以$apply帮他触发一下。),$apply在执行了参数函数之后自动调用 $rootScope.$digest (就是从更作用于开始遍历每一个$scope.$$watchers队列)


      如果你对自己的逻辑比较清楚,可以不使用$apply,改用$scope.$digest(),只遍历当前与其子作用域。不用从rootScope开始

      如果不是很了解逻辑,建议还是使用$apply()从rootScope开始,避免需要更新的值没有被更新,并且$apply会把参数函数放在try...catch里面,如果逻辑发生错误。会把错误传给$exceptionHandler service来处理。

    $scope.data = 0;
    $scope.data2 = 0;
    // code 1
    setInterval(function() {
      $scope.$apply(function() {
        $scope.data++;
        console.log('first:', $scope.data)
      });
    }, 2000);
    
    // code 2
    setInterval(function() {
      $scope.data2++;
      console.log('second:', $scope.data2)
      $scope.$apply();    // 对比code1,少了try...catch
      // $scope.$digest();  // 只遍历当前及其子作用域的$$watchers队列
    },2000)

    一次脏检测中$digest()执行的次数?

      在一个脏检测中,digest至少会执行两次

      因为某一个监听属性的listener可能会改变另一个监听属性的值。因此,angular需要在一次$digest()之后判断这一轮digest中时候有没有属性发生变化并执行了listener,如果有,angular必须再次调用$digest();当已经连续触发了10次$digest(),若还有属性发生变化,angular就会认为你的逻辑错了并console报告。因此在$scope.$watch时要自己多加注意理解好逻辑问题。

    什么时候会触发脏检测?

      好像不少人有一个误区。angular是定时执行脏检测的!!!!(我之前还问过,angular设置多久执行一次脏检测,无言以对)

      angular并不是定时的。会触发脏检测的有以下:

      1. controller 初始化
      2. 几乎所有ng-开头的事件(ng-click,ng-change...)
      3. http请求
      4. $timeout,$interval
      5. 手动调用$apply(), $digest()

      回头想想,如果是定时的,怎么会有脱离angualr环境的说法呢?

  • 相关阅读:
    查找文件的绝对路径
    购买成都二手商品房交易流程(卖方存在欠银行贷款的情况)
    针对CCTV摄像头的扫描爆破工具 :Cameradar
    交换机的基本配置
    思科交换机和路由器的远程配置
    安装Windows和Ubuntu双系统--Ubuntu安装过程识别不了硬盘
    SpringBoot 配置
    Tomcat9在CentOS7上启动慢解决办法,实测可行
    Linux安装JDK
    电影分享——《小丑》
  • 原文地址:https://www.cnblogs.com/miaowwwww/p/6261947.html
Copyright © 2020-2023  润新知