[In short] you need to change one line in your current code
onClick() {
this._ngZone.runOutsideAngular(() => {
setTimeout(()=>this.num = 2,0); // instead of this.num = 2;
}}));
}
now if you click the on the <button>, this.num will become 2, but you won't see any change in the UI (a temporary inconsistency between view and model)
[Explanation] without runOutsideAngular(), async functions like addEventListener() or setTimeout() behaves differently (monkey patched). their callbacks will try to update UI with Angular after running user's code.
For example, you can treat (click)="onClick()" as:
addEventListener("click",function modifiedCallback(){
onClick();
updateUIifModelChanges(); //call to Angular
})
In order to not triggered UI update we need to satisfy the following two conditions:
- not modify model in function
onClick (so, modify inside setTimeout())
- when the model is indeed modified, do not invoke
updateUIifModelChanges (call setTimeout() inside runOutsideAngular)
[More] of cause, the explanation I gave is a very very...simplified version of what happens. setTimeout() has the same function signature whether it's running inside runOutsideAngular() or not. The reason that it behaves differently is because it's running in a different Zone