• 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);

  • 相关阅读:
    password
    bzoj 1458: 士兵占领
    国家集训队2011 happiness
    cogs 2051. 王者之剑
    uva 10779 Collectors Problem
    [Jxoi2012]奇怪的道路
    天神下凡
    藏宝图
    黑红树
    愤怒的小鸟
  • 原文地址:https://www.cnblogs.com/leee/p/5441866.html
Copyright © 2020-2023  润新知