AngularJS的作用域$scope监视

本文介绍AngularJS中$watch方法的应用,包括如何监视作用域属性的变化及解除监视。探讨了$digest循环的工作原理及其触发机制,还讨论了在特定场景下如何通过$timeout服务来自动触发$digest循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

$watch()

使用$watch()方法监视作用域中属性的变化
例子:监视&解除监视
<!doctype html>
<html ng-app="watchModule">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../angular-1.5.5/angular.js">
    </script>
</head>
<body>
    <input ng-model='num' type='number'/>
    <div>change count: {{count}}</div>
    <script>
        angular.module('watchModule',[])
             .run(['$rootScope',function($rootScope){
                    $rootScope.count = 0;
                    $rootScope.num = 100;
                    var unbindWatcher= $rootScope
                    .$watch('num',function(newValue,oldVaule){
                        if(newValue == 2){
                            unbindWatcher();
                        }
                        $rootScope.count++;

                    })
             }]);
    </script>
</body>
</html>


每当文本框内容发生变化时,count值增加;当文本框中的内容为2的时候,将会调用unbindWatcher()解除作用域的监视

当我们使用类似如下代码时:

<input id="input" type="text" ng-model="name"/>
<div id="output">{{name}}</div>
AngularJS框架会在幕后为我们在$scope中设置一个watcher,用来在数据发生变化的时候更新view,这里的watcher跟前面讲的手动调用的$watch()方法所添加的watcher是一样的

$digest

AngularJS又是怎样知道作用域某个属性发生了变化??
AngularJS周期性地运行一个函数来检查scope模型中的数据是否发生了变化,即$digest循环
在ng-click指令,以及其他一些能够让我们更改模型数据的AngularJS内置指令和服务(如ng-model指令,$timeout服务等)更改模型数据时,AngularJS将自动地通过调用$digest()来触发一轮$digest循环,当$digest循环开始后,它会触发每个watcher,这些watcher会检查scope中的当前属性值是否和上一次$digest循环时的属性值相同。如果不同,对应的回调方法就会被执行。
AngularJS其实并不直接调用$digest()方法,而是调用$scope.$apply(),而$scope.$apply()会调用$rootScope.$digest()

在有些情况下,模型数据修改后需要手动调用$apply()方法来触发$digest循环,例如使用JS的setTimeOut()方法来更新一个模型数据,AngularJS框架就没办法知道我们修改了什么,也就无法触发$digest循环了。

修改前:

<!doctype html>
<html ng-app="msgModule">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../angular-1.5.5/angular.js">
    </script>
</head>
<body> 
    <div ng-controller="MsgController">
        <div>
            <button ng-click="scheduleTask()">3秒后回显信息
            </button>
        </div>
        <div>
            {{message}}
        </div>
    </div>
    <script>
        angular.module('msgModule',[]).controller('MsgController',
            function($scope) {
                $scope.scheduleTask = function() {
                    setTimeout(function() {
                        $scope.message = '信息内容';
                        console.log('message='+$scope.message);
                    }, 3000);
                }
            });
    </script>
</body>
</html> 

修改后

<!doctype html>
<html ng-app="msgModule">
<head>
    <meta charset="UTF-8">
    <title>ch05_11</title>
    <script type="text/javascript" src="../angular-1.5.5/angular.js">
    </script>
</head>
<body> 
    <div ng-controller="MsgController">
        <div>
            <button ng-click="scheduleTask()">3秒后回显信息
            </button>
        </div><br/><br/>
        <div>
            {{message}}
        </div>
    </div>
    <script>
        angular.module('msgModule',[]).controller('MsgController',
            function($scope) {
                $scope.scheduleTask = function() {
                    setTimeout(function() {
                        $scope.$apply(function(){
                            $scope.message = '信息内容';
                            console.log('message='+$scope.message);
                        });
                    }, 3000);
                }
            });
    </script>
</body>
</html>


$timeout
$timeout与$interval服务(功能与JS的setTimeout()和setInterval()方法相同,但是可以自动触发$digest循环 )
<!doctype html>
<html ng-app="msgModule">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../angular-1.5.5/angular.js">
    </script>
</head>
<body> 
    <div ng-controller="MsgController">
        <div>
            <button ng-click="scheduleTask()">3秒后回显信息
            </button>
        </div><br/><br/>
        <div>
            {{message}}
        </div>
    </div>
    <script>
        angular.module('msgModule',[]).controller('MsgController',
            function($scope,$timeout) {
                $scope.scheduleTask = function() {
                    $timeout(function() {
                        $scope.message = '信息内容';
                        console.log('message='+$scope.message);
                    }, 3000);
                }
            });
    </script>
</body>
</html>








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值