Change detection triggered by events
ngDoCheck ( ) : void {
console . log ( '%c Change detection triggered' , 'color: red; font-weight: bold; font-size: 18px' ) ;
}
< button (click) ="noop() "> NOOP</ button >
@ViewChild ( 'button' ) button: ElementRef ;
ngAfterViewInit ( ) : void {
this . button . nativeElement . addEventListener ( 'click' , ( ) => { } )
}
document . querySelector ( 'button' ) . addEventListener ( 'click' , ( ) => { } )
@ViewChild ( 'buttonElement' ) buttonElement: ElementRef ;
constructor ( private ngZone : NgZone ) { }
ngAfterViewInit ( ) : void {
this . ngZone . runOutsideAngular ( ( ) => {
this . buttonElement . nativeElement . addEventListener ( 'click' , ( ) => {
} )
} )
}
@Directive ( {
selector : '[safeClick]'
} )
export class SafeClickDirective implements OnInit {
@Output ( )
safeClick = new EventEmitter ( ) ;
constructor ( private hostElement : ElementRef ,
private renderer : Renderer2 ,
private ngZone : NgZone ) { }
ngOnInit ( ) : void {
this . ngZone . runOutsideAngular ( ( ) => {
this . renderer . listen ( this . hostElement . nativeElement , 'click' , ( ) => {
this . safeClick . emit ( ) ;
} )
} )
}
}
If you don't need to update the view - dont run CD on this event
Sometimes you are not aware
@Directive ( {
selector : '[tooltip]'
} )
export class TooltipDirective implements OnInit {
private _element : HTMLElement ;
@Input ( 'tooltip' ) contentToShow : string ;
constructor ( hostElement : ElementRef ) {
this . _element = hostElement . nativeElement
}
ngOnInit ( ) : void {
tippy ( this . _element , { content : this . contentToShow } )
}
}
< ul >
< li *ngFor ="let item of items; index as i "
tooltip ="tip for {{ i }} ">
Item #{{i}}
</ li >
</ ul >
Not all elements needs CD to work
this . ngZone . runOutsideAngular ( ( ) => {
tippy ( this . _element , { content : this . contentToShow } )
} )
CD runs to keep the view updated
Events that don't directly update the view - can run outside
3rd party libraries that register events should run outside