AngularJS--$watch用法 整理

angularJS 双向绑定原理

AngularJS 在scope 上有一个监听队列($$watchers),只要使用了ng-* 指令或者{ {…}}引用了scope上的变量,就会创建对应的监听器($watch),用于监听数据的变化并更新view。当浏览器接收到可以被 angular context 处理的事件时,$digest 循环就会触发。$digest 会遍历所有的 $watch。从而更新DOM

创建监听器的方法
  1. 通过ng-*指令或者{ {…}}引用scope上的变量
  2. 通过scope上的$watch方法手动创建监听器
$watch API

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

  • watchExpression(监听的对象):字符串表达式或者一个function
  • listener(监听到上述的表达式的结果发生变化时触发的回调函数):function(newVal, oldVal, scope)
  • objectEquality(选填的参数,判断对listener中的newVa和oldVal是否使用 angular.equals进行比较):true/false

监听器详解

默认的监听器
姓名:
姓名: { {lastName}} 姓名: { {lastName}}
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
    setTimeout(function () {
        console.log($scope.$$watchers.length);  //3
    });
});

由上面的例子,可以看出,监听器的数量与$scope上定义了什么属性和方法没有具体的联系,只要使用了ng-*指令或者{ {…}},

angularJS就会默认创建对应的 $watch,即使对同样的属性使用多个{ {…}},监听器的数量也是根据ng-*指令或者{ {…}}的数量。

手动创建监听器

1.$watch

$scope.person = {
    firstName: "John",
    lastName: "Doe"
};
$scope.list = [];
$scope.countList = [];

var count = 0;

$scope.changeFn = function () {
    count++;
    $scope.list.push(count);
};

$scope.countNum = function () {
    return count;
};

$scope.$watch('person.firstName', function () {
    console.log('firstName changed');
});

$scope.$watch('person', function (newVal,oldVal) {
    console.log('num changed');  //监听不到Person的内容发生变化,此时person是个对象,newVal===oldVal判断的是引用地址,person的地址没有改变
});


$scope.$watch('person', function (newVal,oldVal) {
    console.log('person changed');  //当第三个参数为true时,newVal和oldVal对比通过angular.equals 方法
},true);


$scope.$watch('countList', function (newVal,oldVal) {
    console.log('countList changed');//与对象Person相同,newVal和oldVal对比通过angular.equals 方法,能监听数组的长度或数组中某一项的内容的改变
}, true);

$scope.$watch('countList.length', function () {
    console.log('countList.length changed:' + $scope.countList.length);  //此时的监听对象是countList的length属性,只要countList.length的返回内容是监听的内容
});

$scope.$watch('countNum()', function () {
    console.log('countNum changed:'); 此时的监听对象是方法的返回结果,只要方法的返回结果发生改变,就会触发这个回调方法,如果countNum方法没有返回内容,即默认返回undefined,不触发回调
});

2.$watch优化

$scope.$watch('lastName', function (newVal, oldVal) {
    if (newVal === oldVal || oldVal === undefined) {
        console.log('first load');
    } else {
        $scope.person.firstName = $scope.person.lastName;
        console.log('lastName changed');
    }
});

如果lastName属性一开始就有值,newVal === oldVal
如果lastName属性一开始没有定义在scope上,此时定义scope.lastname = ‘a’;此时newVal = ‘a’,lastVal = undefined。
上面的方法能实现,当lastname的值发生变化时,才触发要执行的回调函数,避免初始化的过程中,调用给回调函数。

你可能感兴趣的:(AngularJs)