zoukankan      html  css  js  c++  java
  • Angular:手动脏检查/$apply/$digest和监控对象/$watch

    声明:借鉴好多chm资料、视频、PDF总结如下:

    一、$apply的引入

    • View

    <div ng-app="">
    		<div ng-controller="firstController">
    			<input  ng-model="date"/>		
    			{{date}}
    		</div>
    	</div>
    
    • 原生js函数,不能实现刷新(因为没有实现双向绑定(脏检查))

    var firstController = function($scope) {
    	$scope.date = new Date().getSeconds();
    	setInterval(function() {
    		//并没有触发 脏检查
    		$scope.date = new Date().getSeconds();
    
    	}, 1000)
    }
    
    • 原生js函数,在变量改变外面加上$scope.apply(fun),手动实现脏检查,实现刷新

    var firstController = function($scope) {
    	$scope.date = new Date().getSeconds();
    	setInterval(function() {
    		$scope.$apply(function() {
    			$scope.date = new Date().getSeconds();
    			//....会去触发脏检查
    		})
    	}, 1000)
    }
    
    • Angular内置函数,默认已经实现脏检查,实现刷新

    var firstController = function($scope, $interval) {
    	$scope.date = new Date().getSeconds();
    	$interval(function() {
    		$scope.date = new Date().getSeconds();
    	}, 1000)
    }
    
    原生js:setInterval(fun)<==>$interval(fun) 一直循环执行
    原生js:setTimeout(fun)<==>$TimeOut(fun)  执行一次
    
    • gif图结果

    • 解释

       以`ng-开头的` `事件` `指令`和默认`内置的函数`最后`都会执行脏检查`。
       `原声js`要实现如此功能,必须`在变量改变外面加上$scope.apply(fun)`,这样会将这个`apply内的变量复制出一份`,`新值和旧值(备份)对比`,实现双向绑定
    

    二、$watch监听一个对象

    $watch(watchExpression, [listener], [objectEquality]);

    • 两个参数

    <div ng-app="">
    		<div ng-controller="firstController">
    			<input type="text" value="" ng-model="name"/><br/>
    			注意:页面加载的时候执行一次,默认1:改变次数:{{count}}
    			<br/>
    			注意:当次数超过5,页面改变一次,count会+2,触发2次
    		</div>
    	</div>
    
    var firstController = function($scope) {
        $scope.name = '李可';
        $scope.count = 0;
        // 监听一个model 当一个model每次改变时 都会触发第2个函数
        $scope.$watch('name', function(newValue, oldValue) {
           $scope.count=$scope.count+1;//页面加载的时候执行一次
            if ($scope.count > 5) {//当次数超过5,页面改变一次,count会+2,触发2次
                $scope.name = '已经大于5次了';
            }
        });
    }
    
    • gif图结果

    • 问题:为什么触发2次呢?

    估计要分析脏检查的源码了:原谅我处于菜鸟阶段
    问了一些人


    • 三个参数 第三个为true,表示对象内部的属性。深深地监视

    <div ng-app="">
    		<div ng-controller="firstController">
    			<input type="text" value="" ng-model="data.name"/>
    			<input type="text" value="" ng-model="data.age"/>
    			<input type="text" value="" ng-model="count2"/>
    		</div>
    	</div>
    
    var firstController = function($scope) {
        $scope.data = {
            name: '李可',
            age: 18
        }
        $scope.count2 = 0;
        $scope.$watch('data', function() {
            ++$scope.count2;
            if ($scope.count2 > 3) {
                $scope.data.age = '换超过3了';
            }
        }, true)
    }
    
    ++i先加后用(同一个表达式内用)
    i++先用(同一个表达式内用)后加
    var a=2;++a;var b=a*3;alert(b)//9    ++a;var b=a*3;是两表达式
    var c=2;c++;var d=c*3;alert(d)//9   c++;var d=c*3;是两表达式
    var e=2;f=e++;alert(f)//2       f=e++  有++表达式和=表达式   相当f=e; e=e+1
    var g=2;h=++g;alert(h)//3       h=++g; 有++表达式和=表达式   相当g=g+1; h=g;
    var i=2;x=++i +1;alert(x)//4    x=++i +1;  有++表达式和+表达式  相当i=i+1; x=i;
    var m=2;y=m++ +1;alert(y)//3    x=i++ +1;  有++表达式和+表达式   相当y=m; m=m+1
    
    • gif图结果

    注意:页面加载1次,`加1`
    到临界条件时,`加2`,`以后也加1`
    

    延伸


    有了上述方法:我们可以监控 对象、数组。为了少第三个参数,具体数组操作,angular又增加
    $watchCollection(obj, listener);,$watchGroup(watchExpressions, listener);

  • 相关阅读:
    ASP.NET在禁用视图状态的情况下仍然使用ViewState对象【转】
    Atcoder Regular Contest 061 D Card Game for Three(组合数学)
    Solution 「CERC 2016」「洛谷 P3684」机棚障碍
    Solution 「CF 599E」Sandy and Nuts
    Solution 「洛谷 P6021」洪水
    Solution 「ARC 058C」「AT 1975」Iroha and Haiku
    Solution 「POI 2011」「洛谷 P3527」METMeteors
    Solution 「CF 1023F」Mobile Phone Network
    Solution 「SP 6779」GSS7
    Solution 「LOCAL」大括号树
  • 原文地址:https://www.cnblogs.com/leee/p/5441866.html
Copyright © 2011-2022 走看看