没有使用* ngFor调用Angular鼠标

时间:2018-03-28 14:02:12

标签: angular ngfor mouseenter mouseleave

如果使用* ngFor:

生成(mouseleave)指令,则该指令不起作用
@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:如果你足够快地移动鼠标,你可以看到一些div&#34;卡住&#34;在悬停状态。

screenshot after fast mouse movement

有没有办法强制使用mouseleave?

2 个答案:

答案 0 :(得分:2)

mouseentermouseleave不是问题。这是因为从角度渲染,请参阅此thread

所以逻辑是,当mouseenterdiv时(慢),它实际上会调用两次。您可以按功能调试它。

<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)
  }

即使您放置e.stopPropagation();它也不起作用,因为angular会更改hoverdivs并重新渲染模板并最终再次触发mouseenter。它会打两次电话。

这里的步骤:

  1. 的mouseenter
  2. 角度更改值为true
  3. 触发位置最后一只鼠标
  4. 因为同一div再次触发mouseenter
  5. 在你的情况下,你有快速移动鼠标的问题而不是将值true改为false导致角度完成渲染后,角度不再调用mouseenter

    要解决此问题,您应该避免模板重新渲染。

    播放DEMO

答案 1 :(得分:1)

* {1}}数组用于* ngFor,这意味着每次检测到数组中的更改时,angular将呈现所有div。

当您hoverdivsmouseenter时,您更改了数组,从而触发了div的渲染。你所迷过的div现在是 new div。

您可以通过使用角度不会检测到更改的内容来避免这种情况,例如对象数组而不是布尔数组。

更改mouseleavehoverdivs = [ false, false, false, false, false ]

如果替换整个对象,Angular将仅检测数组中的更改。如果您只是更改数组中对象的属性,它将无法检测到数组中的更改。

工作演示:http://plnkr.co/edit/nftBj9W4wKC2K5Se9xEr?p=info