Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@HostListener cause change detection triggers too many times when I'm listening for outside click

I have next template of root component, that draws 9 tiles:

<ul>
  <li *ngFor="let x of [0,1,2,3,4,5,6,7,8]">
    <tile></tile>
  </li>
</ul>

and next tile component, where I added HostListener for document click:

import {AfterViewChecked, Component, HostListener} from '@angular/core';

@Component({
  selector: 'tile',
  template: '<p>tile works!</p>'
})
export class TileComponent implements AfterViewChecked {

  ngAfterViewChecked(): void {
    console.log('checked');
  }

  @HostListener('document:click', ['$event'])
  onOutsideClick(event: any): void {
      // do nothing ...
  }

}

Plunker: http://plnkr.co/edit/7wvon25LhXkHQiMcwh48?p=preview

When I run this I see that on each click change detection was called 9^2 times: enter image description here

I can't understand why.

Can somebody explain to me why change detection triggers n^2 times in this case?

like image 604
Artem Avatar asked Jun 14 '17 13:06

Artem


2 Answers

Short answer - That is by design.

Since we have a click handler, angular triggers change detection after handler been called.

So, when the first component handles click it cause change detection. Then all the components print "checked".

And that repeated for each component, so I've got 9^2 prints "checked."

And one additional note that OnPush strategy will not help to reduce an amount of prints.

like image 187
Artem Avatar answered Sep 22 '22 03:09

Artem


@Hostlistener can be costly. Check my answer here to minimize the effect and improve performance. Detect click outside Angular component

like image 43
ginalx Avatar answered Sep 24 '22 03:09

ginalx