首页 > 解决方案 > 材质对话框中的 DebounceTime runOutsideAngular

问题描述

我正在尝试在 mat-dialog 弹出窗口中过滤对象列表。我的实现基于这篇非常好的帖子,以避免在每个 keyUp 事件中运行 Angular 更改检测。

实施过滤器后,我在ngDoCheck更改检测周期中使用控制台日志进行了验证。似乎每个 keyUp 事件都触发了几个更改检测周期。

我弄清楚了我作为示例的帖子和我的帖子之间的区别:我在一个 Material Dialog 组件中。

我准备了一个stackblitz 示例来展示它。被FormComponent集成两次,一次直接在 中AppComponent,一次在 中mat-dialog。打开您的控制台并观察cdfiltering字符串,它们分别记录更改检测周期和项目过滤。您会注意到,当您使用对话框版本时,有大量的cd.

完整代码在这个地址

有没有办法在 mat-dialog 中停用更改检测?如果是,有什么副作用?

MatDialog 的 API 不包含任何与我正在搜索的内容相似的内容...

请注意,我的代码确实可以正常执行,但是大量的更改检测周期可能会降低较慢设备上的应用程序性能。

希望有人能帮忙!

编辑

根据评论,我尝试将 ChangeDetectionStrategy 切换为onPush(这不应该有任何副作用,因为绑定是使用在去抖动时间后重新分配的过滤列表执行的)。然而,这无济于事。

我还尝试使用以下代码将我的组件与更改检测分离:

ngAfterViewInit() {
  this.ngzone.runOutsideAngular(() => {
    this.filterChangedSubscription = Observable.fromEvent(this.itemfilter.nativeElement, 'keyup')
    .debounceTime(600)
    .subscribe((keyboardEvent: any) => {
      this.items = this.unfilteredItems.filter(
        item => item.toLowerCase().indexOf(keyboardEvent.target.value.toLowerCase()) > -1
      );
      this.cdref.detectChanges();
    });
  });
  this.cdref.detach();
}

我试图禁用我的组件的检测更改(保持触发过滤器的输入),但似乎在每个keyUp事件中仍会多次调用更改检测挂钩。

我怀疑mat-dialog组件会将自己注册到keyUp事件中以获取可访问性快捷方式并触发更改检测。随时分享您的想法。

标签: angularmodal-dialogangular-materialangular-changedetection

解决方案


推荐阅读