[In short] you need to change one line in the current code
onClick() { this._ngZone.runOutsideAngular(() => { setTimeout(()=>this.num = 2,0); // instead of this.num = 2; }})); }
now, if you click on <button> , this.num will become 2 , but you will not see any changes in the user interface (temporary mismatch between the view and the model)
[Explanation] without runOutsideAngular() , asynchronous functions like addEventListener() or setTimeout() behave differently ( monkey fixed) . their callbacks will try to update the interface using Angular after user code is run. For example, you can consider (click)="onClick()" as:
addEventListener("click",function modifiedCallback(){ onClick(); updateUIifModelChanges();
In order not to start updating the user interface, we need to fulfill the following two conditions:
- don't change the model in the
onClick function (so, change inside setTimeout() ) - when the model is really modified, do not call
updateUIifModelChanges (call setTimeout() inside runOutsideAngular )
[More] reasons, the explanation I gave is a very ... simplified version of what is happening. setTimeout() has the same function, regardless of whether it works inside runOutsideAngular() or not. The reason she behaves differently is because she works in another Zone.
source share