Core points
- The
$watch
function in AngularJS is a powerful tool for observing changes in variable values or expressions. When a change is detected, it triggers a callback function that is executed every time the monitored variable changes. -
$watch
Use JavaScript's equality operator (===) for comparison. If the new value is different from the old value, the callback function is triggered. However, it should be noted that by default,$watch
only checks for reference equality, which means that the callback function is triggered only when a new value is assigned to the monitored variable. - AngularJS also provides
$watchGroup
and$watchCollection
as convenient shortcuts for setting up multiple monitors or monitoring arrays or objects with the same callback function, respectively. However, these methods only perform shallow monitoring and react only to reference changes. - Using
$watch
, especially on multiple variables, may affect performance because changes in all monitored variables need to be checked for each summary cycle. Developers should consider using$watchGroup
or$watchCollection
depending on the situation, or limit the number of monitored variables to improve performance.
This article was reviewed by Mark Brown. Thanks to all the peer reviewers of SitePoint for getting SitePoint content to its best!
AngularJS offers many different options to use the publish-subscribe mode through three different "watch" methods. Each method takes optional parameters to modify its behavior.
The official documentation about $watch
is far from exhaustive: after all, this is a problem that bothers AngularJS v1 as a whole. Even online resources that explain how to proceed are fragmented at best.
So, ultimately, it is difficult for developers to choose the right approach for a particular situation. This is especially true for beginners in AngularJS! The results can be surprising or unpredictable, which inevitably leads to errors.
In this article, I will assume that you are familiar with the AngularJS concept. If you feel you need to review, you may need to read about $scope
, bindings, and $apply
and $digest
.
Check your understanding
For example, what is the best way to monitor the first element of an array? Suppose we declare an array on our scope, $scope.letters = ['A','B','C']
;
- When we add elements to an array, will
$scope.$watch('letters', function () {...});
trigger its callback function? - When we change its first element, will it fire? Where is
-
$scope.$watch('letters[0]', function () {...});
? Will it work the same way, or is it better? - Above, the array element is the original value: What if we replace the first element with the same value?
- Now assume that the array contains objects: What happens? What is the difference between
-
$watch
,$watchCollection
and$watchGroup
?
If you are confused by all these questions, please continue reading. My goal is to walk you through the process by explaining this as clearly as possible with a few examples.
$scope.$watch
Let's start with $scope.$watch
. Here is the core of all watch features: every other method we will see is just a convenient shortcut to $watch
.
Using$watch
The advantage of Angular is that you can explicitly use the same mechanism to perform complex operations triggered by data changes in the controller. For example, you can set up a monitor for certain data that can be changed in response to:
- Timeout
- UI
- Complex asynchronous calculations performed by Web Worker
- Ajax call
You can set up just one listener to handle any data changes, no matter what the cause is.
However, to do this, you need to call $scope.$watch
yourself.
Practical Operation
Let's look at the code of $rootscope.watch()
.
This is its signature: function(watchExp, listener, objectEquality, prettyPrintExpression)
.
In detail, its four parameters:
-
watchExp
Monitored expression. It can be a function or a string, and it is evaluated in every digest cycle.A key aspect to note here is that If the expression is evaluated as a function, the function needs to be idempotent. In other words, for the same input set it should always return the same output. If this is not the case, Angular will assume that the monitored data has been changed. This in turn means it will continue to detect differences and call the listener in each iteration of the digest cycle.
-
listener
A callback function that is fired when the monitor is first set up, and then every time a change in thewatchExp
value is detected during the summary cycle. The initial call at setting is intended to store the initial value for the expression. -
objectEquality
The monitor will perform a depth comparison if and only if this value is true. Otherwise, it performs shallow comparisons, i.e. only comparison references.Let's take array as an example:
$scope.fruit = ["banana", "apple"]
;objectEquality == false
means that only the reassignment of thefruit
field will cause the listener to be called.We also need to check how deep the “deep” is: we will discuss this later.
-
prettyPrintExpression
If passed, it will override the monitoring expression. This parameter is not intended to be used in normal calls to$watch()
; it is used internally by the expression parser.Beware: As you can see yourself, unexpected results are prone to unexpected results when the fourth parameter is passed accidentally.
Now we are going to answer some of the questions in the introduction. Please check out the examples of this section:
Feel free to familiarize yourself with them; you can directly compare behavior differences, or do it in the order in the article.
Monitoring Array
So you need to monitor the array on the scope to make changes, but what does "change" mean?
Suppose your controller looks like this:
app.controller('watchDemoCtrl', ['$scope', function($scope){ $scope.letters = ['A','B','C']; }]);
One option is to use a call like this:
$scope.$watch('letters', function (newValue, oldValue, scope) { // 对 $scope.letters 执行任何操作 });
In the above callback, newValue
and oldValue
have self-explanatory meanings and are updated every time the $digest
cycle calls it. The meaning of scope
is also intuitive, because it holds references to the current scope.
But the key is: When will this listener be called? In fact, you can add, delete, replace elements in an array without anything happening. This is because, by default, letters
assumes that you only want $watch
reference equality, so the callback function is triggered only when you assign a new value to . $scope.letters
as the third parameter to true
(i.e. as the value of the optional watch
parameter described above). objectEquality
$scope.$watch('letters', function (newValue, oldValue, scope) { // 对 $scope.letters 执行任何操作 }, true);Surveillance object
For objects, the situation does not change: if
is false, you just monitor any reassignment to that scope variable, and if true, the callback function will be triggered every time the element in the object is changed. objectEquality
It is worth noting that by monitoring the array using
, each time the callback function is triggered, objectEquality === true
and newValue
will be the old and new values of the entire array. So you have to compare them with each other to understand what actually changes. oldValue
as the first argument: $watch
$scope.$watch('letters[4]', function (newValue, oldValue, scope) { //... }, true);What happens if the array has only 2 elements? No problem, your callback function won't be fired unless you add a fourth element. OK OK, technically it fires when you set up the monitor and then only when you add the fourth element.
If you record oldValue
, you will see that in both cases it will be undefined. Compare this to what happens when monitoring existing elements: When set up, you still have oldValue == undefined
. So $watch
cannot be processed!
A more interesting question now: Do we need to pass objectEquality === true
here?
Short answer: Sorry, there is no short answer.
It really depends on:
- In this example, since we are working on the original value, we do not need depth comparisons, so we can omit
objectEquality
. - But, suppose we have a matrix, for example
$scope.board = [[1, 2, 3], [4, 5, 6]]
; and we want to monitor the first row. Then we might want to get an alert when an assignment like$scope.board[0][1] = 7
changes it.
Fields of monitoring objects
Perhaps more useful than monitoring any element in an array, we can monitor any field in an object. But that's not surprising, right? After all, an array in JavaScript is a object.
app.controller('watchDemoCtrl', ['$scope', function($scope){ $scope.letters = ['A','B','C']; }]);
How deep is the depth?
At this point, we also need to clarify one last but crucial detail: What happens if we need to monitor a complex nested object where each field is a non-primitive value? For example, a tree or graph, or just some JSON data.
Let's check it out!
First of all, we need an object to monitor:
$scope.$watch('letters', function (newValue, oldValue, scope) { // 对 $scope.letters 执行任何操作 });
Let's set up the monitor for the entire object: I think so far it's clear that in this case objectEquality
must be set to true
.
$scope.$watch('letters', function (newValue, oldValue, scope) { // 对 $scope.letters 执行任何操作 }, true);
The question is: if assignments like $scope.b.bb[1].bb2a = 7;
happen, will Angular be kind enough to let us know?
The answer is: Yes, luckily, it will (see in the previous CodePen demo).
Other methods
$scope.$watchGroup
$watchGroup()
Is it really a different approach? The answer is no, it is not.
$watchGroup()
is a convenient shortcut that allows you to set up multiple monitors using the same callback function and pass an array of watchExpressions
.
Each passed expression will be monitored using the standard $scope.$watch()
method.
$scope.$watch('letters[4]', function (newValue, oldValue, scope) { //... }, true);
It is worth noting that using $watchGroup
, newValues
and oldValues
will save the list of values of the expression, including the values that have changed and those that have kept the same value, in the order of them in the first parameter The order of passing in the array is the same.
If you checked the documentation for this method, you may notice that it does not take the objectEquality
option. This is because it shallowly monitors expressions and only reacts to reference changes.
If you use the $watchGroup()
demo below, you may be surprised by some subtleties. For example, unshift
will cause the listener to be called, at least to some extent: This is because when passing the expression list to $watchGroup
, any triggers an expression that will result in execution Callback function.
will not produce any updates - updates will only be generated if a new value is assigned to the b field itself. $scope.obj.b
$scope.$watchCollection
This is another convenient shortcut to monitor arrays or objects. For arrays, the listener is called when any element is replaced, deleted, or added. For objects, when any properties are changed. Again, does not allow $watchCollection()
, so it only shallowly monitor elements/fields and does not react to changes in their subfields. objectEquality
Conclusion
Hope these examples help you discover the power of this Angular feature and understand how important it is to use the right options.Feel free to copy CodePen and try to use these methods in different contexts and don't forget to leave your feedback in the comments section!
If you want to have a deeper look at some of the concepts we discussed in this article, here are some suggestions for further reading:
- AngularJS scope
- Understand Angular's
- and
$apply()
$digest()
Emerging Patterns in JavaScript Event Processing - Prototype inheritance in AngularJS scope
- Documents of
- etc.
$watch
FAQs (FAQ)$watch
in AngularJS
$watch
What is the main purpose in AngularJS?
The $watch
function in AngularJS is mainly used to observe changes in the value of a variable or expression. It is part of AngularJS scoped object to monitor changes in the value of a variable or expression. When a change is detected, the $watch
function triggers a callback function that is executed every time the monitored variable changes.
$watch
How does it work in AngularJS?
The $watch
function in AngularJS works by comparing the old and new values of the monitored variable or expression. It uses JavaScript's equality operator (===) for comparison. If the new value is different from the old value, the $watch
function will trigger the callback function.
How do I use $watch
in AngularJS?
To use $watch
in AngularJS, you need to call the $watch
method on the scope object and pass it two parameters: the name of the variable or expression to be monitored, and happens when the variable being monitored The callback function to be executed when changing. Here is an example:
app.controller('watchDemoCtrl', ['$scope', function($scope){ $scope.letters = ['A','B','C']; }]);What is the difference between
$watch
and $apply
in AngularJS?
The function in $watch
in AngularJS is used to observe changes in variables or expressions, while the $apply
function is used to manually start the AngularJS digest period, which checks for any changes in the monitored variable and updates the view accordingly. The $apply
function is usually used when making model changes outside the AngularJS context, such as in the DOM event handler or the setTimeout
function.
Can I monitor multiple variables in AngularJS using $watch
?
Yes, you can use $watch
to monitor multiple variables in AngularJS. You can do this by passing an array of variable names to the $watch
function. However, remember that monitoring multiple variables can affect performance, because the $watch
function needs to check for changes in all monitored variables in each digest cycle.
How do I stop monitoring variables in $watch
in AngularJS?
When you call the $watch
function in AngularJS, it returns a logout function. You can call this function to stop monitoring variables. Here is an example:
$scope.$watch('letters', function (newValue, oldValue, scope) { // 对 $scope.letters 执行任何操作 });
What is $watchGroup
in AngularJS?
The $watchGroup
function in AngularJS is used to monitor a set of expressions. It works like the $watch
function, but it triggers the callback function only once per digest cycle, even if multiple monitored expressions change. This can improve performance when monitoring multiple expressions.
What is $watchCollection
in AngularJS?
The $watchCollection
function in AngularJS is used to monitor the attributes of an object or elements of an array. It triggers the callback function as long as any attribute or element changes, but unlike $watch
, it does not deeply monitor objects or arrays, which can improve performance.
Can I use $watch
in AngularJS directive?
Yes, you can use $watch
in the AngularJS directive. In fact, it is common to use $watch
in directives to respond to changes in attributes or scope variables of directives.
What are the performance considerations in AngularJS using $watch
?
Using $watch
in AngularJS can affect performance, especially when monitoring many variables or expressions. This is because the $watch
function needs to check the changes of all monitored variables in each digest cycle. To improve performance, consider using $watchGroup
or $watchCollection
according to the situation, or limit the number of monitored variables.
The above is the detailed content of Mastering $watch in AngularJS. For more information, please follow other related articles on the PHP Chinese website!

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr

Node.js excels at efficient I/O, largely thanks to streams. Streams process data incrementally, avoiding memory overload—ideal for large files, network tasks, and real-time applications. Combining streams with TypeScript's type safety creates a powe

The differences in performance and efficiency between Python and JavaScript are mainly reflected in: 1) As an interpreted language, Python runs slowly but has high development efficiency and is suitable for rapid prototype development; 2) JavaScript is limited to single thread in the browser, but multi-threading and asynchronous I/O can be used to improve performance in Node.js, and both have advantages in actual projects.

JavaScript originated in 1995 and was created by Brandon Ike, and realized the language into C. 1.C language provides high performance and system-level programming capabilities for JavaScript. 2. JavaScript's memory management and performance optimization rely on C language. 3. The cross-platform feature of C language helps JavaScript run efficiently on different operating systems.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

SublimeText3 Mac version
God-level code editing software (SublimeText3)

SublimeText3 Linux new version
SublimeText3 Linux latest version

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft
