为什么在使用带箭头功能的 canvas.toBlob() 时未触发 Angular 的 ChangeDetection?

Why is Angular's ChangeDetection not triggered when using canvas.toBlob() with an arrow function?

我在 Angular 10 中有一个非常简单的组件。提交表单后,将创建并存储 canvas 元素的 Blob

因此 onSubmit() 函数的相关部分如下所示:

onSubmit(): void {
  const canvas: HTMLCanvasElement = getCanvas();

  canvas.toBlob((blob: Blob) => {
    this.service.create(blob).pipe(first()).subscribe((response: boolean) => {
      this.isSuccessful = response;
    });
  }, 'image/png', 1);
}

问题是,isSuccessful改变了,但是这些改变没有反映在 模板.

所以我所做的是手动触发变化检测,使用 ChangeDetectorRef:

onSubmit(): void {
  const canvas: HTMLCanvasElement = getCanvas();

  canvas.toBlob((blob: Blob) => {
    this.service.create(blob).pipe(first()).subscribe((response: boolean) => {
      this.isSuccessful = response;
      this.cdr.detectChanges();
    });
  }, 'image/png', 1);
}

现在,这行得通了。 但为什么这里需要它? 在所有其他情况下,当我使用这样的箭头函数时,不需要更改检测器。 toBlob() 方法似乎与此不同。

PS:当 service.create() 方法在 toBlob() 方法之外时,也不需要 cdr

未触发更改检测,因为 canvas.toBlobAngular Zone. An alternative to calling ChangeDetectorRef.detectChanges is to make sure that the code is executed inside the Angular zone with NgZone.run 之外执行回调:

import { NgZone } from '@angular/core';
...

constructor(private ngZone: NgZone) { }

canvas.toBlob((blob: Blob) => {
  this.ngZone.run(() => {
    // Run the code here
  });
}, 'image/png', 1);

有关演示,请参阅 this stackblitz