angular $watch


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

我們再回到第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++) {
      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);
}

注意CartController 的底部,我們在totalCart() 的值上面設置了一個監控,用來計算此次購物的總價。只要這個值發生變化,監控器就會調用calculateDiscount() , 然后我們就可以把折扣設置為相應的值。如果總價超過100美元,我們將會把折扣設置為10美元。否則,折扣為0。

 

angular


免責聲明!

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



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