You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.0 KiB
201 lines
5.0 KiB
# AngularJS - Watch and Apply
|
|
|
|
## Lesson Objectives
|
|
|
|
1. Use $watch to listen for changes on variables
|
|
1. Use $apply to force a redraw of the page
|
|
|
|
## Use $watch to listen for changes on variables
|
|
|
|
### Use 1
|
|
|
|
We can create event listeners for any property of the $scope variable. This can be useful if you have a scope variable that changes frequently from multiple sources, but you want to perform the same action each time it updates.
|
|
|
|
```javascript
|
|
$scope.$watch('somevar', function(newValue, oldValue){
|
|
//will run whenever $scope.somevar changes
|
|
});
|
|
```
|
|
|
|
### Example 1
|
|
|
|
file: index.html
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html >
|
|
<head>
|
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js'></script>
|
|
<script type="text/javascript" src="js/app.js"></script>
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<main ng-controller="MainController as main">
|
|
{{somevar}}
|
|
<button ng-click="main.changeScopeVar();">Click Me</button>
|
|
</main>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
const app = angular.module('MyApp', []);
|
|
|
|
app.controller('MainController', ['$scope', function($scope){
|
|
$scope.somevar = 'foo';
|
|
|
|
$scope.$watch('somevar', function(newValue, oldValue){
|
|
//will run whenever $scope.somevar changes
|
|
console.log(newValue, oldValue);
|
|
});
|
|
|
|
this.changeScopeVar = function(){
|
|
$scope.somevar = 'bar';
|
|
};
|
|
}]);
|
|
```
|
|
|
|
### Use 2
|
|
|
|
If no string is passed as first parameter. Entire scope is watched. This is useful for controller properties when controller alias is not known.
|
|
|
|
**NOTE** that the two parameters for the old value and new value of $scope will appear identical, since they both point to the same object in memory.
|
|
|
|
```javascript
|
|
$scope.$watch(function(newValue, oldValue){
|
|
//will run whenever $scope changes
|
|
//NOTE: newValue and oldValue will have same property values, since both point the same object, which has been modified
|
|
});
|
|
```
|
|
|
|
### Example 2
|
|
|
|
file: index.html
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html >
|
|
<head>
|
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js'></script>
|
|
<script type="text/javascript" src="js/app.js"></script>
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<main ng-controller="MainController as main">
|
|
{{somevar}}
|
|
<button ng-click="main.changeScopeVar();">Click Me</button>
|
|
</main>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
const app = angular.module('MyApp', []);
|
|
|
|
app.controller('MainController', ['$scope', function($scope){
|
|
$scope.somevar = 'foo';
|
|
|
|
$scope.$watch(function(newValue, oldValue){
|
|
//will run whenever $scope.somevar changes
|
|
console.log(newValue, oldValue);
|
|
});
|
|
|
|
this.changeScopeVar = function(){
|
|
$scope.somevar = 'bar';
|
|
};
|
|
}]);
|
|
```
|
|
|
|
### Use 3
|
|
|
|
You can also watch any variables by passing in a function as the first param that returns the variable to be watched
|
|
|
|
```javascript
|
|
$scope.$watch(function(){ return foo; }, function(newValue, oldValue){
|
|
//will fire when global foo variable is changed
|
|
});
|
|
```
|
|
|
|
### Example 3
|
|
|
|
file: index.html
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html >
|
|
<head>
|
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js'></script>
|
|
<script type="text/javascript" src="js/app.js"></script>
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<main ng-controller="MainController as main">
|
|
<button ng-click="main.clickFunction()">Click Me</button>
|
|
</main>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
const app = angular.module('MyApp', []);
|
|
|
|
const someThirdPartyVariable = 'foo';
|
|
|
|
app.controller('MainController', ['$scope', function($scope){
|
|
$scope.$watch(
|
|
function(){ return someThirdPartyVariable; },
|
|
function(newValue, oldValue){
|
|
//will fire when global foo variable is changed
|
|
console.log(newValue, oldValue);
|
|
}
|
|
);
|
|
|
|
this.clickFunction = function(){
|
|
someThirdPartyVariable = 'bar';
|
|
}
|
|
}]);
|
|
```
|
|
|
|
## Use $apply to force a redraw of the page
|
|
|
|
Angular doesn't watch $scope properties constantly for changes. This would be processing intensive. Instead, it has listeners for events like ng-click, ng-submit, etc. When these fire, Angular looks at the scopes to see if anything changes. If there's a change, Angular will call the $digest cycle, which basically means it will redraw the view.
|
|
|
|
If you change a $scope property outside of the Angular environment (perhaps through a third party JS library), the view won't refresh. You can manually force the $digest cycle, though. To do this, simply call:
|
|
|
|
```javascript
|
|
$scope.$apply(function(){
|
|
//once the code in here completes, force the $digest cycle to run
|
|
});
|
|
```
|
|
|
|
### Example
|
|
|
|
file: index.html
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html >
|
|
<head>
|
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js'></script>
|
|
<script type="text/javascript" src="js/app.js"></script>
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<main ng-controller="MainController as main">
|
|
{{foo}}
|
|
<button>Click Me</button>
|
|
</main>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
const app = angular.module('MyApp', []);
|
|
|
|
app.controller('MainController', ['$scope', function($scope){
|
|
$scope.foo = 'foo';
|
|
|
|
document.querySelector('button').addEventListener('click', function(){
|
|
$scope.$apply(function(){
|
|
$scope.foo = 'bar';
|
|
})
|
|
})
|
|
}]);
|
|
```
|