angularJS使用$watch监控数据模型的变化
2016-02-16 17:46
681 查看
使用$watch监控数据模型的变化
在scope 内置的全部函数中,用得最多的可能就是$watch 函数了。当你的数据模型中某一部分发生变化时,$watch 函数能够向你发出通知。你能够监控单个对象的属性。也能够监控须要经过计算的结果(函数),实际上仅仅要能够被当作属性訪问到,或者能够当作一个JavaScript 函数被计算出来,就能够被$watch 函数监控。它的函数签名为
当中每一个參数的具体含义例如以下。
watchFn
该參数是一个带有Angular 表达式或者函数的字符串,它会返回被监控的数据模型的当前值。这个表达式将会被运行非常多次。所以你要保证它不会产生其它副作用。也就是说,要保证它能够被调用非常多次而不会改变状态。基于相同的原因。监控表达式应该非常easy被计算出来。假设你使用字符串传递了一个Angular 表达式,那么它将会针对调用它的那个作用域中的对象而运行。
watchAction
这是一个函数或者表达式,当watchFn 发生变化时会被调用。假设是函数的形式,它将会接收到watchFn 的新旧两个值,以及作用域对象的引用。其函数签名为function(newValue, oldValue, scope)。
deepWatch
假设设置为true,这个可选的布尔型參数将会命令Angular 去检查被监控对象的每一个属性是否发生了变化。假设你想要监控数组中的元素。或者对象上的全部属性,而不仅仅是监控一个简单的值,你就能够使用这个參数。因为Angular 须要遍历数组或者对象。假设集合比較大,那么运算负担就会比較重。
$watch 函数会返回一个函数。当你不再须要接收变更通知时,能够用这个返回的函数注销监控器。
假设我们须要监控一个属性。然后接着注销监控。我们能够使用下面代码:
我们再回到第1 章的购物车案例。把它的功能扩充完整。
比如。当用户加入到购物车中的商品价值超过100 美元的时候,我们会给他10 美元的折扣。我们将会使用以下这样的模板:
而CartController 看起来可能像以下这样:
注意CartController 的底部,我们在totalCart() 的值上面设置了一个监控,用来计算此次购物的总价。
仅仅要这个值发生变化,监控器就会调用calculateDiscount(), 然后我们就能够把折扣设置为对应的值。假设总价超过100 美元,我们将会把折扣设置为10 美元。
否则,折扣为0。
图2-1 展示了用户将会看到的效果。
在scope 内置的全部函数中,用得最多的可能就是$watch 函数了。当你的数据模型中某一部分发生变化时,$watch 函数能够向你发出通知。你能够监控单个对象的属性。也能够监控须要经过计算的结果(函数),实际上仅仅要能够被当作属性訪问到,或者能够当作一个JavaScript 函数被计算出来,就能够被$watch 函数监控。它的函数签名为
$watch(watchFn, watchAction, deepWatch)
当中每一个參数的具体含义例如以下。
watchFn
该參数是一个带有Angular 表达式或者函数的字符串,它会返回被监控的数据模型的当前值。这个表达式将会被运行非常多次。所以你要保证它不会产生其它副作用。也就是说,要保证它能够被调用非常多次而不会改变状态。基于相同的原因。监控表达式应该非常easy被计算出来。假设你使用字符串传递了一个Angular 表达式,那么它将会针对调用它的那个作用域中的对象而运行。
watchAction
这是一个函数或者表达式,当watchFn 发生变化时会被调用。假设是函数的形式,它将会接收到watchFn 的新旧两个值,以及作用域对象的引用。其函数签名为function(newValue, oldValue, scope)。
deepWatch
假设设置为true,这个可选的布尔型參数将会命令Angular 去检查被监控对象的每一个属性是否发生了变化。假设你想要监控数组中的元素。或者对象上的全部属性,而不仅仅是监控一个简单的值,你就能够使用这个參数。因为Angular 须要遍历数组或者对象。假设集合比較大,那么运算负担就会比較重。
$watch 函数会返回一个函数。当你不再须要接收变更通知时,能够用这个返回的函数注销监控器。
假设我们须要监控一个属性。然后接着注销监控。我们能够使用下面代码:
... var dereg = $scope.$watch('someModel.someProperty', callbackOnChange()); … dereg();
我们再回到第1 章的购物车案例。把它的功能扩充完整。
比如。当用户加入到购物车中的商品价值超过100 美元的时候,我们会给他10 美元的折扣。我们将会使用以下这样的模板:
<div ng-controller="CartController"> <div ng-repeat="item in items"> <span>{{item.title}}</span> <input ng-model="item.quantity"> <span>{{item.price | currency}}</span> <span>{{item.price * item.quantity | currency}}</span> </div> <div>Total: {{totalCart() | currency}}</div> <div>Discount: {{bill.discount | currency}}</div> <div>Subtotal: {{subtotal() | currency}}</div> </div>
而CartController 看起来可能像以下这样:
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++) { totaltotal = 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); }
注意CartController 的底部,我们在totalCart() 的值上面设置了一个监控,用来计算此次购物的总价。
仅仅要这个值发生变化,监控器就会调用calculateDiscount(), 然后我们就能够把折扣设置为对应的值。假设总价超过100 美元,我们将会把折扣设置为10 美元。
否则,折扣为0。
图2-1 展示了用户将会看到的效果。
相关文章推荐
- 深入浅析AngularJS和DataModel
- angular 异步处理模式promise---$q
- AngularJS在大型单页面应用中的性能优化
- AngularJS和DataModel
- AngularJS中实现日志服务
- POJ2836 Rectangular Covering(状压DP)
- angularJS框架的注意
- Angularjs 源码分析-setupModuleLoader
- angularJS双向数据绑定
- 学习使用AngularJS文件上传控件
- 深入浅析AngularJS和DataModel
- 优化Angular应用的性能
- 基于AngularJs的上传控件-angular-file-upload
- Angular 学习系列 - - angular.bind、angular.bootstrap、angular.copy
- Angular 学习系列 - - $rootScope.Scope
- Angular 学习系列 - - ngIf、ngSwitch、ngHide/ngShow
- Angular 学习系列 - - 脏值检查及其相关
- Angular 学习系列 - - ngInclude、ngTransclude
- Angular 学习系列 - - angular.uppercase、angular.lowercase、angular.fromJson、angular.toJson
- Angular 学习系列 - - $cacheFactory