1
votes

I am using a BehaviorSubject that acts as a state for a child component

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

In the child component template I subscribe to the state using the async pipe

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

Then I update the child component state with the scroll event

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

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

  });
}

Now in Parent component, the change detection is being triggered by the child component scroll event

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

The problem is that the logic depends on the scroll event, and I don't want it to trigger a change detection in the parent component. knowing that I use OnPush change detection strategy in both parent and child component

Is this normal? how can I avoid it?

Here is a minimal reproduction https://stackblitz.com/edit/angular-hkwvy4?file=src%2Fapp%2Fhello.component.ts

1
The link to the stackblitz is not valid. - ConnorsFan
@ConnorsFan I fixed it now! - Murhaf Sousli
This is how angular change detection working. Since angular is tree of components Whenever asynchronus process happen, The change detection will triggered from app-root to bottom. - Chellappan வ
@Chellappan Not sure, here the opposite is happening, parent would not console log 'Parent View Checked!' if I didn't subscribe to the scroll event in the child - Murhaf Sousli

1 Answers

0
votes

This is late, but for anyone still looking for a solution:

Why this is happening: Async pipes are special and are something the OnPush change detection strategy pays attention to. This article has a section specifically dedicated to the async pipe and contains a full explanation plus a lot of other relevant info: https://www.mokkapps.de/blog/the-last-guide-for-angular-change-detection-you-will-ever-need/

Potential Alternative: There are a lot of ways you could do this, but here is one quick solution that accomplishes change detection for scroll inside a child component and does not trigger change detection in the parent. https://stackblitz.com/edit/angular-b3ubyo?file=src%2Fapp%2Fhello.component.ts