angular之$watch, $watchGroup

$watch

$watch主要是用来监听一个对象,在对象发生变化时触发某个事件。

用法:

$scope.$watch(watchFn,watchAction, deepWatch)

接下来讲一下这几个参数:

参数说明
watchFnangular表达式或函数的字符串
watchAction(newValue,oldValue,scope)watchFn发生变化会被调用
deepWatch可选的布尔值命令检查被监控的对象的每个属性是否发生变化

注意:deepWatch为布尔值,true时可以用来监测对象,false一般是用来监测个别元素。watchFn一般是在html中的ng-model标签。

举个例子:

<body ng-controller="MainCtrl">
  <input ng-model="user.name" />
  Name updated: {{updated}} times.
</body>
app.controller('MainCtrl', function($scope) {
  $scope.user = { name: "Fox" };

  $scope.updated = 0;

  $scope.$watch('user', function(newValue, oldValue) {
    if (newValue === oldValue) { return; }
    $scope.updated++;
  }, true);  //必须有true
});

$watch默认情况下是比较两个对象所引用的是否相同,当我们在监听$scope.user时,如果改变$scope.user.name时,对$scope.user的引用是不会改变的,此时检测不到值的变化。但是在$watch中加入第三个参数为true时,就能每次去比较对象的值而不是引用。

$watchGroup()和$watchCollection()

看个例子:

<div ng-controller="ctrl">

    <!-- $watch -->
    <div>
      <input type="text" ng-model="value1"/>
    </div>
    <div ng-bind="w1"></div>
    
    <!-- $watchGroup -->
    <div>
      <input type="text" ng-model="value2"/>
      <input type="text" ng-model="value3"/>
    </div>
    <div ng-bind="w2"></div>
    
    <!-- $watchCollection -->
    <ul>
      <li ng-repeat="v in arr" ng-bind="v"></li>
    </ul>
    <div ng-bind="w3"></div>
  </div>
angular.module('myApp', [])
        .controller("ctrl", ["$scope", "$timeout", function ($scope, $timeout) {
        
          // $watch
          var watcher = $scope.$watch("value1", function (newVal, oldVal) {
            $scope.w1 = "$watch--" + "new:" + newVal + ";" + "old:" + oldVal;
            if (newVal == 'clear') {//设置一个注销监听的条件
              watcher(); //注销监听
            }
          });
          
          
          // $watchGroup
          $scope.$watchGroup(["value2", "value3"], function (newVal, oldVal) {
            //注意:newVal与oldVal都返回的是一个数组
            $scope.w2 = "$watchGroup--" + "new:" + newVal + ";" + "old:" + oldVal;
          });
          
          
          //  $watchCollection
          $scope.arr = ['nick', 'ljy', 'ljj', 'zhw'];
          $scope.$watchCollection('arr', function (newVal, oldVal) {
            $scope.w3 = "$watchCollection--" + "new:" + newVal + ";" + "old:" + oldVal;
          });
          $timeout(function () {
            $scope.arr = ['my', 'name', 'is', 'nick'];
          }, 2000);
        }]);