Let's say you want to watch a model on scope which is defined as:
$scope.model = {firstName: 'John', lastName: 'Doe'};
the watcher can be written in 3 different ways below:
1.value
$scope.$watch('model', function(value) {
//watches any change to each item
//everytime the watcher will fire when firstName or lastName changes
console.log(value.firstName);
console.log(value.lastName);
});
2.new and old value
$scope.$watch('model', function(newVal, oldVal) {
//You get reference of new and old value of model
//normally object reference equality is checked
//if (newVal === oldVal)
console.log(newVal.firstName);
console.log(oldVal.firstName);
});
3.directly from scope
$scope.$watch('model', function() {
//watches any change to each item
//access from scope directly
//You are inside only when anything has changed on model
console.log($scope.model.firstName);
});
As an add-on you can also deep watch an object if necessary as:
$scope.$watch('model', function(newVal, oldVal) {
//watch changes
}, true);
deep watch/object equality will trace changes from the object graph till the root node. For example for a model like:
$scope.model = { firstName: 'John', lastName: 'Doe', address: { zip: 1234 } };
watch would also fire for changes to zip
in address
.
It is not only the object you can watch but also specify a function whose return value can be watched. The function takes the scope
as parameter by default:
$scope.$watch(function(scope) {
return scope.model.firstName;
}, function(newVal, oldVal) {
//Only watch the first name
console.log(newVal.firstName);
console.log(oldVal.firstName);
});