Angular 2中使用ngZone.runOutsideAngular与requestAnimationFrame循环

4

根据我在线阅读的资料,Angular团队建议您始终在Angular区域之外调用requestAnimationFrame(),如下所示:

this.ngZone.runOutsideAngular(() => {
  requestAnimationFrame(timestamp => {
    let timerStart = timestamp || new Date().getTime();
    this.myAnimeMethod(timestamp);
  });
});

但循环中的问题如何处理呢?

this.ngZone.runOutsideAngular(() => {
  requestAnimationFrame(timestamp => {
    let timerStart = timestamp;
    this.myAnimeMethod(timestamp, timerStart);
  });
});

myAnimeMethod(timestamp, timerStart) {
  let time = timestamp || new Date().getTime();
  let runtime = time - timerStart;

  /// animation logic here

  if(runtime < 10000) {

    // ------- continue to animate for 10 seconds -- //

    requestAnimationFrame(timestamp => {
      this.myAnimeMethod(timestamp, timerStart);
    });
  }
}

第一次请求时调用this.ngZone.runOutsideAngular()是否就足够了,还是在myAnimeMethod()内部再次调用this.ngZone.runOutsideAngular()像这样?

this.ngZone.runOutsideAngular(() => {
  requestAnimationFrame(timestamp => {
    let timerStart = timestamp;
    this.myAnimeMethod(timestamp, timerStart);
  });
});

myAnimeMethod(timestamp, timerStart) {
  let time = timestamp || new Date().getTime();
  let runtime = time - timerStart;

  /// animation logic here

  if(runtime < 10000) {

    // ------- request to run outside of Angular again while continuing to animate for 10 seconds -- //

    this.ngZone.runOutsideAngular(() => {
      requestAnimationFrame(timestamp => {
        this.myAnimeMethod(timestamp, timerStart);
      });
    });

  }
}
2个回答

1
简短回答:如果 requestAnimationFrame 的处理程序来自 Angular 之外的调用,请无需继续调用 NgZone.runOutsideAngular
详细回答:一旦您进入“根”区域(这是在调用 NgZone.runOutsideAngular 时获得的),任何 requestAnimationFrame 回调函数也将从该区域运行,除非您显式请求不同的区域,例如通过 NgZone.run
要检查这一点,请尝试从您的 requestAnimationFrame 处理程序调用静态函数 NgZone.isInAngularZone()
请注意,我使用的是 Angular 4.4.4 和 Zone.js 0.8.18 进行测试。

还有@DevMike,这个还有用吗?我根本无法运行'requestAnimationFrame'。 - Ben Racicot

0

你也可以创建一个 ngzon-flags.ts 文件,把所有的变化检测例外放进去。

// All events inside the BLACK-LIST Array will not trigger updates anymore from angular
// requestAnimationFrame wont trigger change detection
(window as any).__Zone_disable_requestAnimationFrame = true; 
// Same for scroll and mousemove or any other event youll add
(window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove'];

将该文件导入到您的polyfills.ts中:

import './ngzone-flags'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接