What is considered an observer in Angular?

What are considered " watchers " in Angular? Are observers themselves observers, or are other Angular constructs such as ngModel observers?

Or am I missing a big picture? For example, are observers available for directives like ngModel ?

update : is there a way to tell when observers exist? When testing, I want to know when to name the area. $ Digest ()

+5
source share
3 answers

watchers are nothing but a dirty check that keeps track of the old value and the new value

They are evaluated in each digest cycle. It can be a combination of a variable scope or any expression. Angular collects all these observers in each digest and mainatain cycle inside the $$watchers array. you can see how many watchers there are by running console.log($scope.$watchers) inside your controller.

Markup

 <body class="container" ng-controller="myCtrl"> Hello {{test}} I'm test to show $$watchers {{test1}} <div ng-show="show">SHowiing this div using ng-show</div> <div ng-if="show">SHowiing this div using ng-show</div> Watcher is not compulsary that should scope variables {{'1'}} </body> 

Plunkr

Guess in the above code how many watchers there are, as you can see that there are 3 {{}} interpolation directives that are going to be placed in the array of watchers, and then, if you see $scope.$$watchers on the console $scope.$$watchers , it will show 5 observers.

As it turned out, it shows 5 observers. As we only see 3, we actually used the ng-show and ng-if directives, which internally put $watch in the expression specified in its attribute value. and this expression is evaluated in each digest cycle.

You can also create your own custom observer using $watch (deep / simple hours) and $watchGroup

You could also use the $attrs.$observe , this works just like a clock, but the only thing it does is it works for the interpolation variable.

 $attrs.$observe('test',function(value){ alert('') }); 

Most Angular directives internally use observers like ng-repeat , ng-show , ng-if , ng-include , ng-switch , ng-bind , interpolation directive {{}} , filters, etc. They set the watch internally to control two-way binding.

+2
source

Observers (if you take only the documentation on which you are based) are angular mechanisms that seek to observe, in a two-way binding style, a variable or function result during any angular digest cycle; and no matter what the triggering event of the digest cycle will be.

I would call an β€œobserver” any angular mechanism that can trigger some code based on ANY event that can happen.

Typically, to create an observer you should use: $scope.watch(...)

Just keep in mind that it is better to avoid observers as much as we can.
Indeed, their callback will be triggered in EVERY digest cycle to perform a dirty check ; often affecting performance.

ng-model not related to the concept of observer.
ng-model is just a way to bind some variable from view to controller.
These are two different concepts.

+1
source

To illustrate how the functions $ watch (), $ digest (), and $ apply () work, take a look at this example:

 <div ng-controller="myController"> {{data.time}} <br/> <button ng-click="updateTime()">update time - ng-click</button> <button id="updateTimeButton" >update time</button> </div> <script> var module = angular.module("myapp", []); var myController1 = module.controller("myController", function($scope) { $scope.data = { time : new Date() }; $scope.updateTime = function() { $scope.data.time = new Date(); } document.getElementById("updateTimeButton") .addEventListener('click', function() { console.log("update time clicked"); $scope.data.time = new Date(); }); }); </script> 

In this example, the binding of the variable $ scope.data.time to the interpolation directive, which combines the value of the variable into an HTML page. This binding creates a clock inside the $ scope.data.time variable.

The example also contains two buttons. The first button has an ng-click listener attached to it. When this button is pressed, the $ scope.updateTime () function is called, and after that AngularJS calls $ scope. $ Digest (), so the data bindings are updated.

The second button gets a standard JavaScript event listener attached to it from inside the controller function. When the second button is pressed, the listener function is executed. As you can see, the listener functions for both buttons do almost the same thing, but when the second button listen function is called, the data binding is not updated. This is because $ scope. $ Digest () is not called after the second button event listener is executed. Thus, if you press the second button, the time will be updated in the variable $ scope.data.time, but the new time will never be displayed.

To fix this, we can add $ scope. $ digest () call the last line of the button event listener, for example:

 document.getElementById("updateTimeButton") .addEventListener('click', function() { console.log("update time clicked"); $scope.data.time = new Date(); $scope.$digest(); }); 

Instead of calling $ digest () inside the button's listener function, you could also use the $ apply () function as follows:

 document.getElementById("updateTimeButton") .addEventListener('click', function() { $scope.$apply(function() { console.log("update time clicked"); $scope.data.time = new Date(); }); }); 

Notice how the $ scope function. $ apply () is called from within the button's event listener, and as an update to the $ scope.data.time variable, it is executed inside the function passed as a parameter to the $ apply () function. When the call to the $ apply () function ends, AngularJS calls $ digest () internally, so all data bindings are updated.

+1
source

All Articles