$watch
$watch主要是用来监听一个对象,在对象发生变化时触发某个事件。
用法:
$scope.$watch(watchFn,watchAction, deepWatch)
接下来讲一下这几个参数:
参数 | 说明 |
---|---|
watchFn | angular表达式或函数的字符串 |
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()
由于watch()深比较性能较差,angular还提供了$watchGroup([watchExp], listener)和$watchCollection(obj, listener) 方法来分别监听数组和对象。
$watchGroup:
其实是使用watch监听一组watchExp,所以watchGroup不支持深比较
$watchCollection:
比$watch进一步,但是基于性能考虑它只向内关注1层,对数组重新赋值,或是对数组元素进行新增、删除、修改时,回调会被调用,注意只要是修改就会调用,如果给数组赋的值和之前一样也会触发回调。如果某个数组元素内部的某个属性被更新时,回调不会被调用。
看个例子:
<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); }]);