The (mouseleave) directive is not working, if it is generated with *ngFor:
@Component({
selector: 'my-app',
template: `
<ng-container *ngFor="let item of hoverdivs; index as i">
<div style="background-color: grey" (mouseenter)="hoverdivs[i]=true" (mouseleave)="hoverdivs[i]=false">
<p>Hoverable div #{{i}}</p>
<p> hover status: {{item}} </p>
</div>
</ng-container>
`,
})
export class App {
hover:boolean;
hoverdivs = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
constructor() {
}
}
My working example can be seen here: if you move the mouse fast enough, you can see that some of the divs "stuck" on hovering status.
Is there a way to force mouseleave call?
That is not problem from mouseenter
or mouseleave
. It's because render from angular, see this thread.
So the logic is, when mouseenter
to the div
(when slow) it actually call twice. You can debug it by function.
<div style="background-color: grey; height: 80px; margin-bottom: 15px;"
(mouseenter)="fire($event, i)"
(mouseleave)="fire($event, i)">
Hoverable div #{{i}}
hover status: {{hoverdivss[i]}}
</div>
fire(e,key) {
e.stopPropagation();
console.log(key)
}
even you put e.stopPropagation();
it won't work cause angular will change hoverdivs
and re-render template and eventually trigger mouseenter
again. It will call twice.
here steps:
In your case, you have problem fast mouse moving not change value true
to false
cause after angular done render, angular not call mouseenter
again.
To solve this problem you should avoid template re-rendering.
Play DEMO.