Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Angular 2 change detection work?

In Angular 1, change detection was by dirty checking the $scope hierarchy. We would implicitly or explicitly create watchers in our templates, controllers or components.

In Angular 2 we no longer have $scope, but we do override setInterval, setTimeout, et al. I can see how Angular might use this to trigger a $digest, but how does Angular determine what has changed, especially given that Object.observe never made it into browsers?

Example

Here is a simple example. An object defined in a service is updated in a setInterval. The DOM is recompiled each interval.

How is Angular able to tell that the AppComponent is watching the service, and that the value of an attribute of the service has changed?

var InjectedService = function() {   var val = {a:1}   setInterval(() => val.a++, 1000);   return val; }  var AppComponent = ng.core   .Component({     selector: "app",     template:     `       {{service.a}}     `   })   .Class({     constructor: function(service) {       this.service = service;     }   })  AppComponent.parameters = [ new ng.core.Inject( InjectedService ) ];  document.addEventListener('DOMContentLoaded', function() {   ng.platform.browser.bootstrap(AppComponent, [InjectedService]) }); 
like image 833
superluminary Avatar asked Feb 17 '16 22:02

superluminary


People also ask

How does Angular 2 detect changes?

Angular can detect when data changes in the component, and can re-render the view to display the updated data. Angular makes sure that data in the component and the view are always in sync with each other.

How does Angular change detection really work?

Change detection works by detecting common browser events like mouse clicks, HTTP requests, and other types of events, and deciding if the view of each component needs to be updated or not.

What triggers Angular change detection?

By default, angular will run the change detector every time @Input() data is changed or modified. But with OnPush strategy, the change detector is only triggered if the data passed on @Input() has a new reference.

How many types of change detection strategy are there in Angular 2?

Out of the box, Angular provides two different change detection strategies: Default and OnPush.


1 Answers

Angular creates a change detector object (see ChangeDetectorRef) per component, which tracks the last value of each template binding, such as {{service.a}}. By default, after every asynchronous browser event (such as a response from a server, or a click event, or a timeout event), Angular change detection executes and dirty checks every binding using those change detector objects.

If a change is detected, the change is propagated. E.g.,

  • If an input property value changed, the new value is propagated to the component's input property.
  • If a {{}} binding value changed, the new value is propagated to DOM property textContent.
  • If the value of x changes in a style, attribute, or class binding – i.e., [style.x] or [attr.x] or [class.x] – the new value is propagated to the DOM to update the style, HTML attribute, or class.

Angular uses Zone.js to create its own zone (NgZone), which monkey-patches all asynchronous events (browser DOM events, timeouts, AJAX/XHR). This is how change detection is able to automatically run after each asynchronous event. I.e., after each asynchronous event handler (function) finishes, Angular change detection will execute.

I have a lot more detail and reference links in this answer: What is the Angular2 equivalent to an AngularJS $watch?

like image 156
Mark Rajcok Avatar answered Oct 02 '22 16:10

Mark Rajcok