SlideShare a Scribd company logo
AngularJS, More Than Directives!
- Gaurav Behere
- http://www.gauravbehere.in
Topics Covered
A. Apply/Digest Phase Cycle.
B. Handling Memory.
C. Transclusion.
D. Promises.
E. Watch.
Apply/Digest Cycle
$digest:
$digest processes all the watch-Expressions for the current scope and its children
What happens when a watch-Expression is processed?
The value of the current watch-Expression is compared with the value of the previous
watch-Expression, and if they do not match then it is “dirty” and a listener is fired.
This is what we call as “Dirty Checking”.
Angular doesn’t directly call $digest(). Instead, it calls $scope.$apply(), which in turn calls
$rootScope.$digest(). As a result of this, a digest cycle starts at the $rootScope, and
subsequently visits all the child scopes calling the watchers along the way.
Now, let’s assume you attach an ng-click directive to a button and pass a function name to
it. When the button is clicked, AngularJS wraps the function call within $scope.$apply(). So,
your function executes as usual, change models (if any), and a $digest cycle starts to
ensure your changes are reflected in the view.
When & why should I call apply() manually ?
When an external event (such as a user action, timer or XHR) is received, the associated
expression must be applied to the scope through the $apply() method so that all listeners
are updated correctly.
It will account for only those model changes which are done inside AngularJS’ context (i.e.
the code that changes models is wrapped inside $apply()). Angular’s built-in directives
already do this so that any model changes you make are reflected in the view. However, if
you change any model outside of the Angular context, then you need to inform Angular of
the changes by calling $apply() manually. It’s like telling Angular that you are changing
some models and it should fire the watchers so that your changes propagate properly.
For example, if you use JavaScript’s setTimeout() function to update a scope model,
Angular has no way of knowing what you might change. In this case it’s your responsibility
to call $apply() manually, which triggers a $digest cycle. Similarly, if you have a directive
that sets up a DOM event listener and changes some models inside the handler function,
you need to call $apply() to ensure the changes take effect
Example
If you use JavaScript’s setTimeout() function to update a scope model, Angular has no way of
knowing what you might change. In this case it’s your responsibility to call $apply() manually,
which triggers a $digest cycle.
HTML
<body ng-app="myApp">
<div ng-controller="MessageController"> Delayed Message: {{message}} </div>
</body>
JS /*Without Apply*/
angular.module('myApp',[]).controller('MessageController', function($scope) {
$scope.getMessage = function() {
setTimeout(function() {
$scope.message = 'Fetched after 3 seconds';
}, 2000);
$scope.getMessage();
}
JS /*With Apply*/
angular.module('myApp',[]).controller('MessageController', function($scope) {
$scope.getMessage = function() {
setTimeout(function() {
$scope.$apply(function() {
$scope.message = 'Fetched after 3 seconds';
});
}, 2000);
}
$scope.getMessage();
});
Handling Memory
$destroy()
Removes the current scope (and all of its children) from the parent scope. Removal implies
that calls to $digest() will no longer propagate to the current scope and its children. Removal
also implies that the current scope is eligible for garbage collection.
The $destroy() is usually used by directives such as ngRepeat for managing the unrolling of
the loop.
Just before a scope is destroyed a $destroy event is broadcasted on this scope. Application
code can register a $destroy event handler that will give it chance to perform any necessary
clean-up.
Scope.$destroy();
Calling $destroy() on a scope causes an event “$destroy” to flow downstream.
Why & when should I manually handle memory ?
If you are using timers to update scope.
In cases where you have event listeners.
As an example, the following controller continuously updates a model value in one second intervals, and these updates
will continue forever, even after the controller’s view is gone and the scope is removed from its parent.
module.controller("TestController", function($scope, $timeout) {
var onTimeout = function() {
$scope.value += 1;
$timeout(onTimeout, 1000);
};
$timeout(onTimeout, 1000);
$scope.value = 0;
});
Listening for the $destroy event is an opportunity to halt the timer
module.controller("TestController", function($scope, $timeout) {
var onTimeout = function() {
$scope.value += 1;
timer = $timeout(onTimeout, 1000);
};
var timer = $timeout(onTimeout, 1000);
$scope.value = 0;
$scope.$on("$destroy", function() {
if (timer) {
$timeout.cancel(timer);
}
});
});
Promises
The AngularJS $q service is said to be inspired by Chris Kowal's Q library
(github.com/kriskowal/q). The library's goal is to allow users to monitor asynchronous
progress by providing a "promise" as a return from a call. In AngularJS, the semantics of
using a promise are:
var promise = callThatRunsInBackground();
promise.then(
function(answer) {
// do something
},
function(error) {
// report something
},
function(progress) {
// report progress
});
A number of Angular services return promises: $http, $interval, $timeout, for example. All
promise returns are single objects; you're expected to research the service itself to find out
what it returns. For example, for $http.get, the promise returns an object with four
keys:data, status, headers, and config. Those are the same as the four parameters fed to the
success callback if you use those semantics:
// this
$http.get('/api/v1/movies/avengers')
.success(function(data, status, headers, config) {
$scope.movieContent = data;
});
// is the same as
var promise = $http.get('/api/v1/movies/avengers');
promise.then(
function(payload) {
$scope.movieContent = payload.data;
});
Deferring Promises, Defining Custom Promises:
function asyncGreet(name) {
var deferred = $q.defer();
setTimeout(function() {
deferred.notify('About to greet ' + name + '.');
if (okToGreet(name)) {
deferred.resolve('Hello, ' + name + '!');
} else {
deferred.reject('Greeting ' + name + ' is not allowed.');
}
}, 1000);
return deferred.promise;
}
var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
alert('Success: ' + greeting);
}, function(reason) {
alert('Failed: ' + reason);
}, function(update) {
alert('Got notification: ' + update);
});
Chaining Promises
defer.promise
.then(function () {
alert("I promised I would show up");
})
.then(function () {
alert("me too");
})
.then(function () {
alert("and I");
});
defer.resolve();
It is also possible to resolve with parameters. The chained promises will cascade their return values to the
subsequent promise:
defer.promise
.then(function (weapon) {
alert("You can have my " + weapon);
return "bow";
})
.then(function (weapon) {
alert("And my " + weapon);
return "axe";
})
.then(function () {
alert("And my " + weapon);
});
defer.resolve("sword");
Transclusion
Transclusion provides a way for a consumer of a directive to define a template that is
imported into the directive and displayed. For example you might have a directive that
outputs a table while allowing the consumer of the directive to control how the table rows
are rendered. Or, you might have a directive that outputs an error message while allowing
the consumer of the directive to supply HTML content that handles rendering the error
using different colors. By supporting this type of functionality the consumer of the directive
has more control over how specific parts of the HTML generated by the directive are
rendered.
Two key features are provided by AngularJS to support transclusion. The first is a property
that is used in directives named transclude. When a directive supports transclusion this
property is set to true. The second is a directive named ng-transclude that is used to define
where external content will be placed in a directive’s template
Markup
<div ng-app="phoneApp">
<div ng-controller="AppCtrl">
<panel>
<div class="button">Click me!</div>
</panel>
</div>
</div>
var app = angular.module('phoneApp', []);
app.controller("AppCtrl", function ($scope) {
});
app.directive("panel", function () {
return {
restrict: "E",
template: '<div class="panel">This is a panel component</div>'
}
});
return {
restruct: "E",
transclude: true,
template: '<div class="panel" ng-transclude>This is a panel component </div>'
}
Watch
The $scope.watch() function creates a watch of some variable. When you register a watch you pass two functions
as parameters to the $watch() function:
A value function
A listener function
Here is an example:
$scope.$watch(function() {},
function() {}
);
The first function is the value function and the second function is the listener function.
The value function should return the value which is being watched. AngularJS can then check the value returned
against the value the watch function returned the last time. That way AngularJS can determine if the value has
changed. Here is an example:
$scope.$watch(function(scope) { return scope.data.myVar },
function() {}
);
This example value function returns the $scope variable scope.data.myVar. If the value of this variable changes, a
different value will be returned, and AngularJS will call the listener function.
The watchExpression is called on every call to $digest() and should return the value that will
be watched. (Since $digest() reruns when it detects changes the watchExpression can execute
multiple times per $digest() and should be idempotent.)
The listener is called only when the value from the current watchExpression and the previous
call to watchExpression are not equal (with the exception of the initial run, see below).
Inequality is determined according to reference inequality, strict comparison via the !==
Javascript operator, unless objectEquality == true (see next point)
When objectEquality == true, inequality of the watchExpression is determined according to
the angular.equals function. To save the value of the object for later comparison, the
angular.copy function is used. This therefore means that watching complex objects will have
adverse memory and performance implications.
The watch listener may change the model, which may trigger other listeners to fire. This is
achieved by rerunning the watchers until no changes are detected. The rerun iteration limit is
10 to prevent an infinite loop deadlock.
Further Read/References
https://docs.angularjs.org/api/ng/type/$rootScope.Scope
https://thinkster.io/egghead/promises/
http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/
http://andyshora.com/promises-angularjs-explained-as-cartoon.html

More Related Content

PDF
Backbone Basics with Examples
PPTX
Optimizing Angular Performance in Enterprise Single Page Apps
PDF
Writing Maintainable JavaScript
PPTX
Pengenalan blaast platform sdk
PDF
Tinkerbelles return home from their Guinness world-record attempt on Sunday
PDF
MVI - Managing State The Kotlin Way
PDF
Reliable Javascript
PDF
Mad Max is back, plus the rest of our new reviews and notable screenings
Backbone Basics with Examples
Optimizing Angular Performance in Enterprise Single Page Apps
Writing Maintainable JavaScript
Pengenalan blaast platform sdk
Tinkerbelles return home from their Guinness world-record attempt on Sunday
MVI - Managing State The Kotlin Way
Reliable Javascript
Mad Max is back, plus the rest of our new reviews and notable screenings

What's hot (20)

PDF
描画とビジネスをクリーンに分ける(公開用)
PPTX
AngularJS Services
PPTX
Angular Tutorial Freshers and Experienced
PDF
What the FUF?
PPTX
AngularJS: what is underneath the hood
PPTX
AngularJS $Provide Service
PDF
Integrating React.js with PHP projects
PDF
Inversion Of Control
PPTX
Owl: The New Odoo UI Framework
PDF
Angular js routing options
PPT
Backbone.js
PDF
06 jQuery #burningkeyboards
PPTX
jQuery for Beginners
PDF
Ruby - Design patterns tdc2011
PDF
Slightly Advanced Android Wear ;)
PPTX
AngularJS Routing
PPTX
Workshop 1: Good practices in JavaScript
PDF
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
PDF
Async Testing giving you a sinking feeling
PDF
AngularJS Framework
描画とビジネスをクリーンに分ける(公開用)
AngularJS Services
Angular Tutorial Freshers and Experienced
What the FUF?
AngularJS: what is underneath the hood
AngularJS $Provide Service
Integrating React.js with PHP projects
Inversion Of Control
Owl: The New Odoo UI Framework
Angular js routing options
Backbone.js
06 jQuery #burningkeyboards
jQuery for Beginners
Ruby - Design patterns tdc2011
Slightly Advanced Android Wear ;)
AngularJS Routing
Workshop 1: Good practices in JavaScript
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
Async Testing giving you a sinking feeling
AngularJS Framework
Ad

Viewers also liked (11)

PPTX
План дій з реформування підприємств установ
RTF
0531 981 01 90 FULYA KİTAP ALANLAR-PLAK-KİTAP-ANTİKA EŞYA SATIN ALANLAR 0531 ...
PDF
issue176
PPTX
Untitled presentation
PPT
Jka Resume
RTF
0531 981 01 90 YALI KİTAP ALANLAR-PLAK-KİTAP-ANTİKA EŞYA SATIN ALANLAR 0531 9...
PDF
Pcc newsletter letter size 1-12-2012
PDF
Discurso Precade
PDF
Review on Document Recommender Systems Using Hierarchical Clustering Techniques
PDF
Bar Modeling: Using Models to Help Solve Word Problems
PPT
コンセプトアイデア 1
План дій з реформування підприємств установ
0531 981 01 90 FULYA KİTAP ALANLAR-PLAK-KİTAP-ANTİKA EŞYA SATIN ALANLAR 0531 ...
issue176
Untitled presentation
Jka Resume
0531 981 01 90 YALI KİTAP ALANLAR-PLAK-KİTAP-ANTİKA EŞYA SATIN ALANLAR 0531 9...
Pcc newsletter letter size 1-12-2012
Discurso Precade
Review on Document Recommender Systems Using Hierarchical Clustering Techniques
Bar Modeling: Using Models to Help Solve Word Problems
コンセプトアイデア 1
Ad

Similar to AngularJS, More Than Directives ! (20)

PPTX
Scope demystified - AngularJS
PDF
Workshop 14: AngularJS Parte III
PPTX
AngularJs presentation
PDF
AngularJS Workshop
PPTX
Angular js 1.0-fundamentals
PPTX
Optimizing a large angular application (ng conf)
ODP
Angular js-crash-course
PDF
AngularJS Basics
PPTX
Angular workshop - Full Development Guide
PDF
AngularJS - TechTalk 3/2/2014
PPTX
5 angularjs features
ODP
AngularJs Crash Course
PPTX
AngularJS.part1
PPTX
Intro to AngularJs
PPTX
Introduction to Angular JS
PPT
introduction to Angularjs basics
PPTX
Angular js
PPTX
Angular Presentation
PPTX
Practical AngularJS
PDF
Get AngularJS Started!
Scope demystified - AngularJS
Workshop 14: AngularJS Parte III
AngularJs presentation
AngularJS Workshop
Angular js 1.0-fundamentals
Optimizing a large angular application (ng conf)
Angular js-crash-course
AngularJS Basics
Angular workshop - Full Development Guide
AngularJS - TechTalk 3/2/2014
5 angularjs features
AngularJs Crash Course
AngularJS.part1
Intro to AngularJs
Introduction to Angular JS
introduction to Angularjs basics
Angular js
Angular Presentation
Practical AngularJS
Get AngularJS Started!

Recently uploaded (20)

PDF
Embodied AI: Ushering in the Next Era of Intelligent Systems
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PDF
R24 SURVEYING LAB MANUAL for civil enggi
PDF
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PDF
Model Code of Practice - Construction Work - 21102022 .pdf
PPTX
Current and future trends in Computer Vision.pptx
PPT
Project quality management in manufacturing
PPTX
Construction Project Organization Group 2.pptx
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
PDF
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PDF
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
PPTX
additive manufacturing of ss316l using mig welding
PPTX
Geodesy 1.pptx...............................................
DOCX
573137875-Attendance-Management-System-original
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PPTX
Artificial Intelligence
PPTX
Sustainable Sites - Green Building Construction
PPTX
bas. eng. economics group 4 presentation 1.pptx
PDF
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
Embodied AI: Ushering in the Next Era of Intelligent Systems
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
R24 SURVEYING LAB MANUAL for civil enggi
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
Model Code of Practice - Construction Work - 21102022 .pdf
Current and future trends in Computer Vision.pptx
Project quality management in manufacturing
Construction Project Organization Group 2.pptx
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
additive manufacturing of ss316l using mig welding
Geodesy 1.pptx...............................................
573137875-Attendance-Management-System-original
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
Artificial Intelligence
Sustainable Sites - Green Building Construction
bas. eng. economics group 4 presentation 1.pptx
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT

AngularJS, More Than Directives !

  • 1. AngularJS, More Than Directives! - Gaurav Behere - http://www.gauravbehere.in
  • 2. Topics Covered A. Apply/Digest Phase Cycle. B. Handling Memory. C. Transclusion. D. Promises. E. Watch.
  • 3. Apply/Digest Cycle $digest: $digest processes all the watch-Expressions for the current scope and its children What happens when a watch-Expression is processed? The value of the current watch-Expression is compared with the value of the previous watch-Expression, and if they do not match then it is “dirty” and a listener is fired. This is what we call as “Dirty Checking”. Angular doesn’t directly call $digest(). Instead, it calls $scope.$apply(), which in turn calls $rootScope.$digest(). As a result of this, a digest cycle starts at the $rootScope, and subsequently visits all the child scopes calling the watchers along the way.
  • 4. Now, let’s assume you attach an ng-click directive to a button and pass a function name to it. When the button is clicked, AngularJS wraps the function call within $scope.$apply(). So, your function executes as usual, change models (if any), and a $digest cycle starts to ensure your changes are reflected in the view. When & why should I call apply() manually ? When an external event (such as a user action, timer or XHR) is received, the associated expression must be applied to the scope through the $apply() method so that all listeners are updated correctly. It will account for only those model changes which are done inside AngularJS’ context (i.e. the code that changes models is wrapped inside $apply()). Angular’s built-in directives already do this so that any model changes you make are reflected in the view. However, if you change any model outside of the Angular context, then you need to inform Angular of the changes by calling $apply() manually. It’s like telling Angular that you are changing some models and it should fire the watchers so that your changes propagate properly. For example, if you use JavaScript’s setTimeout() function to update a scope model, Angular has no way of knowing what you might change. In this case it’s your responsibility to call $apply() manually, which triggers a $digest cycle. Similarly, if you have a directive that sets up a DOM event listener and changes some models inside the handler function, you need to call $apply() to ensure the changes take effect
  • 5. Example If you use JavaScript’s setTimeout() function to update a scope model, Angular has no way of knowing what you might change. In this case it’s your responsibility to call $apply() manually, which triggers a $digest cycle. HTML <body ng-app="myApp"> <div ng-controller="MessageController"> Delayed Message: {{message}} </div> </body> JS /*Without Apply*/ angular.module('myApp',[]).controller('MessageController', function($scope) { $scope.getMessage = function() { setTimeout(function() { $scope.message = 'Fetched after 3 seconds'; }, 2000); $scope.getMessage(); } JS /*With Apply*/ angular.module('myApp',[]).controller('MessageController', function($scope) { $scope.getMessage = function() { setTimeout(function() { $scope.$apply(function() { $scope.message = 'Fetched after 3 seconds'; }); }, 2000); } $scope.getMessage(); });
  • 6. Handling Memory $destroy() Removes the current scope (and all of its children) from the parent scope. Removal implies that calls to $digest() will no longer propagate to the current scope and its children. Removal also implies that the current scope is eligible for garbage collection. The $destroy() is usually used by directives such as ngRepeat for managing the unrolling of the loop. Just before a scope is destroyed a $destroy event is broadcasted on this scope. Application code can register a $destroy event handler that will give it chance to perform any necessary clean-up. Scope.$destroy(); Calling $destroy() on a scope causes an event “$destroy” to flow downstream.
  • 7. Why & when should I manually handle memory ? If you are using timers to update scope. In cases where you have event listeners. As an example, the following controller continuously updates a model value in one second intervals, and these updates will continue forever, even after the controller’s view is gone and the scope is removed from its parent. module.controller("TestController", function($scope, $timeout) { var onTimeout = function() { $scope.value += 1; $timeout(onTimeout, 1000); }; $timeout(onTimeout, 1000); $scope.value = 0; }); Listening for the $destroy event is an opportunity to halt the timer module.controller("TestController", function($scope, $timeout) { var onTimeout = function() { $scope.value += 1; timer = $timeout(onTimeout, 1000); }; var timer = $timeout(onTimeout, 1000); $scope.value = 0; $scope.$on("$destroy", function() { if (timer) { $timeout.cancel(timer); } }); });
  • 8. Promises The AngularJS $q service is said to be inspired by Chris Kowal's Q library (github.com/kriskowal/q). The library's goal is to allow users to monitor asynchronous progress by providing a "promise" as a return from a call. In AngularJS, the semantics of using a promise are: var promise = callThatRunsInBackground(); promise.then( function(answer) { // do something }, function(error) { // report something }, function(progress) { // report progress });
  • 9. A number of Angular services return promises: $http, $interval, $timeout, for example. All promise returns are single objects; you're expected to research the service itself to find out what it returns. For example, for $http.get, the promise returns an object with four keys:data, status, headers, and config. Those are the same as the four parameters fed to the success callback if you use those semantics: // this $http.get('/api/v1/movies/avengers') .success(function(data, status, headers, config) { $scope.movieContent = data; }); // is the same as var promise = $http.get('/api/v1/movies/avengers'); promise.then( function(payload) { $scope.movieContent = payload.data; });
  • 10. Deferring Promises, Defining Custom Promises: function asyncGreet(name) { var deferred = $q.defer(); setTimeout(function() { deferred.notify('About to greet ' + name + '.'); if (okToGreet(name)) { deferred.resolve('Hello, ' + name + '!'); } else { deferred.reject('Greeting ' + name + ' is not allowed.'); } }, 1000); return deferred.promise; } var promise = asyncGreet('Robin Hood'); promise.then(function(greeting) { alert('Success: ' + greeting); }, function(reason) { alert('Failed: ' + reason); }, function(update) { alert('Got notification: ' + update); });
  • 11. Chaining Promises defer.promise .then(function () { alert("I promised I would show up"); }) .then(function () { alert("me too"); }) .then(function () { alert("and I"); }); defer.resolve(); It is also possible to resolve with parameters. The chained promises will cascade their return values to the subsequent promise: defer.promise .then(function (weapon) { alert("You can have my " + weapon); return "bow"; }) .then(function (weapon) { alert("And my " + weapon); return "axe"; }) .then(function () { alert("And my " + weapon); }); defer.resolve("sword");
  • 12. Transclusion Transclusion provides a way for a consumer of a directive to define a template that is imported into the directive and displayed. For example you might have a directive that outputs a table while allowing the consumer of the directive to control how the table rows are rendered. Or, you might have a directive that outputs an error message while allowing the consumer of the directive to supply HTML content that handles rendering the error using different colors. By supporting this type of functionality the consumer of the directive has more control over how specific parts of the HTML generated by the directive are rendered. Two key features are provided by AngularJS to support transclusion. The first is a property that is used in directives named transclude. When a directive supports transclusion this property is set to true. The second is a directive named ng-transclude that is used to define where external content will be placed in a directive’s template
  • 13. Markup <div ng-app="phoneApp"> <div ng-controller="AppCtrl"> <panel> <div class="button">Click me!</div> </panel> </div> </div> var app = angular.module('phoneApp', []); app.controller("AppCtrl", function ($scope) { }); app.directive("panel", function () { return { restrict: "E", template: '<div class="panel">This is a panel component</div>' } }); return { restruct: "E", transclude: true, template: '<div class="panel" ng-transclude>This is a panel component </div>' }
  • 14. Watch The $scope.watch() function creates a watch of some variable. When you register a watch you pass two functions as parameters to the $watch() function: A value function A listener function Here is an example: $scope.$watch(function() {}, function() {} ); The first function is the value function and the second function is the listener function. The value function should return the value which is being watched. AngularJS can then check the value returned against the value the watch function returned the last time. That way AngularJS can determine if the value has changed. Here is an example: $scope.$watch(function(scope) { return scope.data.myVar }, function() {} ); This example value function returns the $scope variable scope.data.myVar. If the value of this variable changes, a different value will be returned, and AngularJS will call the listener function.
  • 15. The watchExpression is called on every call to $digest() and should return the value that will be watched. (Since $digest() reruns when it detects changes the watchExpression can execute multiple times per $digest() and should be idempotent.) The listener is called only when the value from the current watchExpression and the previous call to watchExpression are not equal (with the exception of the initial run, see below). Inequality is determined according to reference inequality, strict comparison via the !== Javascript operator, unless objectEquality == true (see next point) When objectEquality == true, inequality of the watchExpression is determined according to the angular.equals function. To save the value of the object for later comparison, the angular.copy function is used. This therefore means that watching complex objects will have adverse memory and performance implications. The watch listener may change the model, which may trigger other listeners to fire. This is achieved by rerunning the watchers until no changes are detected. The rerun iteration limit is 10 to prevent an infinite loop deadlock.