angularJS 里的$watch的用法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了angularJS 里的$watch的用法相关的知识,希望对你有一定的参考价值。

参考技术A $watch 方法在用的时候主要是手动的监听一个对象,但对象发生变化时触发某个事件。

需要被检测的对象,可以是以下任意一种:
1.某个数据,监测这个数据的值是否发生变化;
2.一条angular表达式,监测表达式的结果是否发生变化;
3.函数(),监测函数的返回值是否发生变化;
注意:以上都是字符串格式,并且都是在 $scope 作用域下执行的。

监听到变化时执行的函数。

1.newValue: watchObj的新的值;
2.oldValue: watchObj的旧的值;
3.scope: 就是当前控制器的 $scope ;
注意:函数或者表达式不是在 $scope 作用域下执行的,所以,如果是需要调用当前作用域下的某个函数,应该是 scope.watchCallback

布尔值,是否深度监听。
ifDeep值设置为true, 那么angular会检测被监控对象的每个属性是否发生了变化。

1.$watch 单一的变量

2.$watch 多个变量

3.$watch对象或数组

4.$watch 函数的返回结果

1. $observe 是angular指令中link函数第三个参数 ( attrs ) 的一个方法. 只能在指令的link函数中使用它. 它是通过 $evalAsync 函数实现监控的。
2. $watchGroup 是用来监听一组表达式。数组中任意表达式的变化都会触发监听函数。

3. $watchCollection 用来监听一个对象(包括数组), 当这个对象的任意属性发生变化时,触发监听函数。和 $watch 一样,第一次参数可以是一个返回一个对象的函数。

4. $observe, $watch, $watchGroup, $watchCollection 都返回一个移除监听的函数。当需要取消监听的时候,直接调用。

1. $parse,$eval 这两个函数都可以解析表达式的值。它们的区别在于 $parse 是一个服务,可以注入使用。 $eval 是 $scope 对象上的一个方法,我们只能在能访问 $scope 的场景下使用它。
2. $evalAsync 和 $eval 一样用来解析表达式的值。但它并不会立刻计算表达式的值,而是将表达式缓存起来,等到下一次 $digest (脏检查 )的时候执行。以获取更好的性能。

关于angularJS的$watch的 一些小用法

$watch方法,它可以帮助我们在每个scope中监视其中的变量。

$watch 单一的变量

对于普通的变量时,如数字,字符串等,直接如下写是可以监视到变量的变化,并执行相应的函数的。

$scope.count=1;
$scope.$watch(‘count‘,function(){
...
});

$watch 多个变量

对于多个变量的监视变化,执行同一函数的话,可以将这几个变量转为字符串,以‘+’号隔开来进行监视

//当count或page变化时,都会执行这个匿名函数
$scope.count=1;
$scope.page=1;
$scope.$watch(‘count + page‘,function(){
...
});

$watch对象或数组

发现用上面两种方法去监视数组时,会发现即使数组的内容改变了,也没有触发到这个匿名函数。之后发现watch函数其实是有三个变量的,第一个参数是需要监视的对象,第二个参数是在监视对象发生变化时需要调用的函数,实际上watch还有第三个参数,它在默认情况下是false。
当第三个参数是false时,其实watch函数监视的是数组的地址,而数组的内容的变化不会影响数组地址的变化,所以watch函数失灵了。
解决办法,就是在后面添加第三个参数为true就好(当然,也可以将这监听返回结果为JSON字符串形式的该对象或数组的的匿名函数。)

$scope.items=[
{a:1},
{a:2}
{a:3}];
$scope.$watch(‘items‘,function(){...},true);

或者将监听返回结果为JSON字符串形式的该对象或数组的的匿名函数

$scope.items=[
{a:1},
{a:2}
{a:3}];
$scope.$watch(function(){
    return JSON.stringify($scope.items);
},function(){...});

$watch 函数的返回结果

在写代码的时候,有时会遇到要监视一个函数返回的结果是否变化的情况,所以查了一下$watch 监视函数的情况。

方法1:监视对象为“函数名()”的字符串,记得加“()”!

//未完成的任务个数
$scope.unDoneCount = function() {
    var count = 0;
    angular.forEach($scope.todoList, function(todo) {
        count += todo.done ? 0 : 1;
    });
    return count;
};
//单选影响全选部分
$scope.$watch(‘unDoneCount()‘, function(nv) {
    $scope.isDoneAll = nv ? false : true;
});

方法2:在监视对象中设置为匿名函数,返回要监视的函数的返回值(绕晕了…)

$scope.$watch(function(){
    return $scope.unDoneCount();//不要忘了(),要执行的啊~
}, function(nv) {
    $scope.isDoneAll = nv ? false : true;
});

取消$watch

watch的性能消耗好像蛮大的,所以对于已经不需要监视的watch,记得定时取消掉。
至于怎么取消了…查了好久才找到的
其实每个watch函数返回的结果就是这个watch的deregisterWatch()函数

//在chrome的控制台上,断点得到的$watch的返回值
function deregisterWatch() {
    arrayRemove(array, watcher);
    lastDirtyWatch = null;
}

 所以啊,要取消watch的话,一开始将$watch的返回值保存就好啦,要取消watch的时候,在调用。

var count=1;
var unbingWatch=$scope.$watch(‘todoList‘,function(){
    console.log(‘todoList change‘);
    count++;
    //相当于在todoList变化了4次之后,就调用unbingWatch()取消这个watch
    //在第5次todoList改变的时候,就不会输出todoList change了。
    if(count>4){
        unbingWatch();
    }
});

 





以上是关于angularJS 里的$watch的用法的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS $watch 监听

AngularJS中的$watch(),$digest()和$apply()

AngularJS:清除 $watch

AngularJS $watch 的 Angular 等价物是啥?

AngularJS $watch 与 $watchCollection:性能哪个更好?

第一次更新后,AngularJS $watch 数组失败