如何避免子组件滚动事件触发父组件中的更改检测

时间:2019-06-26 23:51:51

标签: angular angular-changedetection

我正在使用BehaviorSubject作为子组件的状态

state = new BehaviorSubject<any>({transform: 'translate3d(0, 0, 0)'});
styleState = this.state.asObservable();

在子组件模板中,我使用async管道订阅状态

<div>{{ styleState | async | json }}</div>

然后我通过滚动事件更新子组件的状态

ngOnInit() {
  this.zone.runOutsideAngular(() => {

    fromEvent(this.el.nativeElement, 'scroll').pipe(
      tap((e: any) => {
        this.zone.run(() => {
          this.state.next({ scrollTop: e.target.scrollTop });
        });
      })
    ).subscribe();

  });
}

现在在“父”组件中,更改检测由子组件滚​​动事件触发

ngAfterViewChecked() {
  console.log('Parent View Checked!');
}

问题在于逻辑取决于滚动事件,我不希望它触发父组件中的更改检测。知道我在父级和子级组件中都使用了OnPush更改检测策略

这正常吗?我该如何避免呢?

这里是复制品https://stackblitz.com/edit/angular-hkwvy4?file=src%2Fapp%2Fhello.component.ts

1 个答案:

答案 0 :(得分:0)

这很晚了,但是对于仍在寻找解决方案的任何人:

为什么会这样: 异步管道非常特殊,,OnPush更改检测策略对此予以关注。本文有专门讨论异步管道的部分,其中包含完整的说明以及许多其他相关信息:https://www.mokkapps.de/blog/the-last-guide-for-angular-change-detection-you-will-ever-need/

可能的选择: 您可以通过多种方式来执行此操作,但是这里有一个快速解决方案,可以完成对子组件内部滚动的更改检测,而不会在父组件中触发更改检测。 https://stackblitz.com/edit/angular-b3ubyo?file=src%2Fapp%2Fhello.component.ts