AngularJS uses $ watch to monitor data model changes. angularjswatch
Use $ watch to monitor data model changes
Among all the built-in functions in scope, the $ watch function is used most often. When a part of your data model changes, the $ watch function can send you a notification. You can monitor the attributes of a single object, or monitor the results (functions) that need to be computed. In fact, as long as they can be accessed as attributes, or they can be computed as a JavaScript function, it can be monitored by the $ watch function. Its function signature is
- $watch(watchFn, watchAction, deepWatch)
The meanings of each parameter are as follows.
WatchFn
This parameter is a string with an Angular expression or function. It returns the current value of the monitored data model. This expression will be executed many times, so make sure it does not produce any other side effects. That is to say, make sure that it can be called many times without changing the status. For the same reason, the monitoring expression should be easily computed. If you use a string to pass an Angular expression, it will be executed for the objects in the scope that calls it.
WatchAction
This is a function or expression that is called when watchFn changes. If it is in the form of a function, it will receive two new and new values of watchFn, and the reference of the scope object. The function signature is function (newValue, oldValue, scope ).
DeepWatch
If it is set to true, this optional Boolean parameter will command Angular to check whether each attribute of the Monitored object has changed. You can use this parameter if you want to monitor elements in an array or all attributes of an object, instead of simply monitoring a simple value. Angular needs to traverse arrays or objects. If the set is large, the computing burden will be heavy.
$ Watch function returns a function. when you no longer need to receive a change notification, you can use this function to log out of the monitor.
If we need to monitor a property and then cancel monitoring, we can use the following code:
- ...
- var dereg = $scope.$watch('someModel.someProperty', callbackOnChange());
- …
- dereg();
Let's go back to the shopping cart case in Chapter 1 and complete its functions. For example, if the value of the item added to the shopping cart is more than 100 USD, we will give him a 10 USD discount. We will use the following template:
- <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>
The CartController may look like the following:
- 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);
- }
Note that at the bottom of CartController, we set a metric on the value of totalCart () to calculate the total price of this purchase. As long as this value changes, the monitor will call calculateDiscount (), and then we can set the discount to the corresponding value. If the total price exceeds $100, we will set the discount to $10. Otherwise, the discount is 0.
Figure 2-1 shows what you will see.