3

我试图阅读很多关于NgZone角度的内容。我知道角度zone.js用于变化检测。我看到一些代码使用了 zone.run 并在其中放置了一些操作。

它实际上是做什么的?

我仍然无法弄清楚实际使用zone.run

this.zone.run(() => {
     /* my code here */
});

在这个链接的帮助下,我明白了一点。

4

1 回答 1

1

答案本身已在您提到的博客中提供。我会尝试进一步分解它。在给定的示例中:

情况:您正在创建一个progress-bar组件,其值将每 10 毫秒更新一次

没有NgZone

一旦button被点击,increaseProgress()将被调用一个函数(进度条完成后将显示其值)

    <button (click)="processWithinAngularZone()">
      Process within Angular zone
    </button>

它每 10 毫秒调用一次,并不断增加this.progress计数器,直到100

increaseProgress(doneCallback: () => void) {
  this.progress += 1;
  console.log(`Current progress: ${this.progress}%`);

  if (this.progress < 100) {
    window.setTimeout(() => {
      this.increaseProgress(doneCallback);
    }, 10);
  } else {
    doneCallback();
  }
}

这将起作用,但是由于我们正在使用setTimeout,因此ChangeDetection每次都会触发循环10 milliseconds,这将影响应用程序的性能


NgZone

ngZone我们一起传递,zone.run()而不是console.logChangeDetection一旦计数器完成,这基本上将作为触发器。

现在,为了避免(由于猴子补丁而触发)的影响setTimeoutChangeDetection,我们将整个执行块包装在里面this.zone.runOutsideAngularChangeDetection仅在我们显式调用 时才会调用zone.run()

  this.zone.runOutsideAngular(() => {
    this.increaseProgress(() => {
      this.zone.run(() => {
        console.log('Outside Done!');
      });
    });
  });

类似的用例:

  1. 假设您需要实现一些逻辑,scrollEvent这些逻辑可能会触发一个可能导致触发ChangeDetection. 为避免这种情况,我们可以使用zone.runOutsideAngular并手动触发ChangeDetection特定动作/持续时间后使用zone.run().

  2. 您正在使用一些 3rd 方库(在 Angular 之外工作ChangeDetection)并且您需要CD在该 3rd 方库的某些事件之后手动触发。

使用它不是很频繁,但是是的,它会在不知道的情况下产生不需要的行为。

我希望它可以帮助您更好地理解这个概念

于 2019-08-10T09:16:52.433 回答