Runtime Terror
Runtime Terror

Reputation: 6742

ngFor is triggering mouseenter on child change

NgFor is triggering mouseenter on parent element every time the child element changes. I want to disable this behaviour but I don't know how. I created a simple example in stackblitz here.

the component:

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  visible;
  mouseenterCalled = 0;
  intervalCalled = 0;

  items$ = interval(2000).pipe(
    map(() => {
      this.intervalCalled++;
      return [`item${this.intervalCalled}`, 'item2', 'item3'];
    })
  );

  onEnter() {
    this.mouseenterCalled++;
    this.visible = true;
  }
}

and the template:

<div (mouseenter)="onEnter()">Hover me | mouseenter was called: {{mouseenterCalled}}x | | interval was called:
  {{intervalCalled}}x</div>
<div *ngIf="visible" (mouseenter)="onEnter()">
  <div>Overlay header</div>
  <div *ngIf="items$ | async as items">
    <p *ngFor="let item of items">{{ item }}</p>
  </div>
</div>

enter image description here

If you hover over Hover me text, the "overlay" will appear. Since the items are generated through interval, they will appear a bit later, but this is ok. Once they're there, hover over the first item. The mouseenter count will increase on every item change, but the listener itself is located on the parent div, not on the item. I've tried with stopPropagation, but it won't help. The events are still triggered. Any idea how could I solve this?

Upvotes: 0

Views: 252

Answers (1)

Chellappan வ
Chellappan வ

Reputation: 27303

Try Adding trackBy function to ngFor

component.html

<div (mouseenter)="onEnter()">Hover me | mouseenter was called: {{mouseenterCalled}}x | | interval was called:
  {{intervalCalled}}x</div>
<div *ngIf="visible" (mouseenter)="onEnter()">
  <div>Overlay header</div>
  <div *ngIf="items$ | async as items">
    <p *ngFor="let item of items;trackBy: trackBy">{{ item }}</p>
  </div>
</div>

component.ts

 trackBy = (item,index)=>{
    return item;
 }

Upvotes: 1

Related Questions