angularJS使用$watch監控數據模型的變化


使用$watch監控數據模型的變化

在scope 內置的全部函數中,用得最多的可能就是$watch 函數了。當你的數據模型中某一部分發生變化時,$watch 函數能夠向你發出通知。你能夠監控單個對象的屬性。也能夠監控須要經過計算的結果(函數),實際上僅僅要能夠被當作屬性訪問到,或者能夠當作一個JavaScript 函數被計算出來,就能夠被$watch 函數監控。它的函數簽名為

  
  
 
 
         
  1. $watch(watchFn, watchAction, deepWatch) 

當中每一個參數的具體含義例如以下。

watchFn

該參數是一個帶有Angular 表達式或者函數的字符串,它會返回被監控的數據模型的當前值。這個表達式將會被運行非常多次。所以你要保證它不會產生其它副作用。也就是說,要保證它能夠被調用非常多次而不會改變狀態。基於相同的原因。監控表達式應該非常easy被計算出來。假設你使用字符串傳遞了一個Angular 表達式,那么它將會針對調用它的那個作用域中的對象而運行。

watchAction

這是一個函數或者表達式,當watchFn 發生變化時會被調用。假設是函數的形式,它將會接收到watchFn 的新舊兩個值,以及作用域對象的引用。其函數簽名為function(newValue, oldValue, scope)。

deepWatch

假設設置為true,這個可選的布爾型參數將會命令Angular 去檢查被監控對象的每一個屬性是否發生了變化。假設你想要監控數組中的元素。或者對象上的全部屬性,而不僅僅是監控一個簡單的值,你就能夠使用這個參數。因為Angular 須要遍歷數組或者對象。假設集合比較大,那么運算負擔就會比較重。

$watch 函數會返回一個函數。當你不再須要接收變更通知時,能夠用這個返回的函數注銷監控器。

假設我們須要監控一個屬性。然后接着注銷監控。我們能夠使用下面代碼:
 

  
  
 
 
         
  1. ...  
  2. var dereg = $scope.$watch('someModel.someProperty', callbackOnChange());  
  3. …  
  4. dereg(); 

我們再回到第1 章的購物車案例。把它的功能擴充完整。

比如。當用戶加入到購物車中的商品價值超過100 美元的時候,我們會給他10 美元的折扣。我們將會使用以下這樣的模板:

  
  
 
 
         
  1. <div ng-controller="CartController"> 
  2. <div ng-repeat="item in items"> 
  3. <span>{{item.title}}</span> 
  4. <input ng-model="item.quantity"> 
  5. <span>{{item.price | currency}}</span> 
  6. <span>{{item.price * item.quantity | currency}}</span> 
  7. </div> 
  8. <div>Total: {{totalCart() | currency}}</div> 
  9. <div>Discount: {{bill.discount | currency}}</div> 
  10. <div>Subtotal: {{subtotal() | currency}}</div> 
  11. </div> 

而CartController 看起來可能像以下這樣:
 

  
  
 
 
         
  1. function CartController($scope) {  
  2. $scope.bill = {};  
  3. $scope.items = [  
  4. {title: 'Paint pots', quantity: 8, price: 3.95},  
  5. {title: 'Polka dots', quantity: 17, price: 12.95},  
  6. {title: 'Pebbles', quantity: 5, price: 6.95}  
  7. ];  
  8. $scope.totalCart = function() {  
  9. var total = 0;  
  10. for (var i = 0len = $scope.items.length; i < len; i++) {  
  11. totaltotal = total + $scope.items[i].price * $scope.items[i].quantity;  
  12. }  
  13. return total;  
  14. }  
  15. $scope.subtotal = function() {  
  16. return $scope.totalCart() - $scope.discount;  
  17. };  
  18. function calculateDiscount(newValue, oldValue, scope) {  
  19. $scope.bill.discount = newValue > 100 ? 10 : 0;  
  20. }  
  21. $scope.$watch($scope.totalCart, calculateDiscount);  

注意CartController 的底部,我們在totalCart() 的值上面設置了一個監控,用來計算此次購物的總價。

僅僅要這個值發生變化,監控器就會調用calculateDiscount(), 然后我們就能夠把折扣設置為對應的值。假設總價超過100 美元,我們將會把折扣設置為10 美元。

否則,折扣為0。

圖2-1 展示了用戶將會看到的效果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM