The main idea behind the push pipe is a new way of handling change detection.
If all values are transported over Observables we know exactly when a value changes and could trigger the change detection.
Even more, we could trigger it only in the needed parts of our application.
In Angular’s ViewEngine there are 2 options to render content:
- markForCheck
- detectChanges
markForCheck marks the related component as dirty and the next change detection of zone.js will trigger the rendering.
In comparison, detectChanges triggers the change detection immediately whether or not_ zone.js_ is present.
Ivy equivalents are:
- ɵdetectChanges
- ɵmarkDirty
As the push pipe should serve as a drop-in replacement for the async pipe, used in Angular v8, v9, and v10 we had to implement only a little change in the pipes code.
Switching from
tap(v => { this.value = v; this.ref.markForCheck(); })
<>
to
tap(v => { this.value = v; this.ref.detectChanges(); })
<>
With that in place we can already run Angular without zone.js.
If we would use it a bit and count the number of change detections we realize that multiple render calls are done for a single change.
A naive example could look like this:
@Component({
selector: 'app-display',
template: `
{{observable$ | push}}
`
})
export class DisplayComponent {
observable$ = of(1, 2, 3);
}
#angular #rxjs #change-detection #push-pipe #reactive-programming #push pipe