AngularJS为我们提供了一个非常方便的$watch方法,它可以帮助我们在每个scope中监视其中的变量,应该只能是类似$scope.value的变量。可以监控单个对象的属性,也可以监控需要经过计算的结果(函数)
$watch(watchFn, watchAction, deepWatch)
watchFn
该参数是一个带有Angular表达式或者函数的字符串,它会返回被监控的数据模型的当前值。这个表达式将会被执行很多次,所以你要保证它不会产生其他副作用。也就是说,要保证它可以被调用很多次而不会改变状态。基于同样的原因,监控表达式应该很容易被计算出来。如果你使用字符串传递了一个Angular表达式,那么它将会针对调用它的那个作用域中的对象而执行。
watchAction
这是一个函数或者表达式,当watchFn 发生变化时会被调用。如果是函数的形式,它将会接收到watchFn的新旧两个值,以及作用域对象的引用。其函数签名为function(newValue, oldValue, scope)。
deepWatch
如果设置为true,这个可选的布尔型参数将会命令Angular去检查被监控对象的每个属性是否发生了变化。如果你想要监控数组中的元素,或者对象上的所有属性,而不只是监控一个简单的值,你就可以使用这个参数。由于Angular需要遍历数组或者对象,如果集合比较大,那么运算负担就会比较重。
$watch 函数会返回一个函数,当你不再需要接收变更通知时,可以用这个返回的函数注销监控器。
如果我们需要监控一个属性,然后接着注销监控,我们可以使用以下代码:
...
var dereg = $scope.$watch('someModel.someProperty', callbackOnChange());
…
dereg();
$scope.name = 'zhangsan';
$scope.count = 0;
$scope.cart = [
{id:1,name:'iphone5s',quantity:3,price:4300},
{id:2,name:'iphone5c',quantity:30,price:3300},
{id:3,name:'mac',quantity:3,price:14300},
{id:4,name:'ipad',quantity:100,price:2000}
];
// 监听一个model 当一个model每次改变时 都会触发第2个函数
$scope.$watch('name', function(newValue, oldValue) {
// console.log(newValue+ '===' +oldValue);
++$scope.count;
if ($scope.count > 3) {
$scope.name = '已将大于3次了';
}
});
$scope.$watch('cart', function(newValue, oldValue) {
// console.log(newValue);
angular.forEach(newValue, function(item, key) {
if(item.quantity < 1) {
var returnKey = confirm('是否从购物车内删除该产品');
if(returnKey) {
$scope.remove(item.id);
}else{
item.quantity = oldValue[key].quantity;
}
return ;
}
});
}, true); ////检查被监控的对象的每个属性是否发生变化
或者监控需要经过计算的结果(函数)
function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.totalCart = function() {
var total = 0;
for (var i = 0, len = $scope.items.length; i < len; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
return total;
}
$scope.subtotal = function() {
return $scope.totalCart() - $scope.discount;
};
function calculateDiscount(newValue, oldValue, scope) {
$scope.bill.discount = newValue > 100 ? 10 : 0;
}
$scope.$watch($scope.totalCart, calculateDiscount);
}