Проблема в потоке данных, когда компонент OnPu sh находится в середине рендеринга, его состояние (свойства класса) должно быть стабильным, но подход в вашем примере нарушает его, потому что наблюдаемое значение было изменено в в середине рендеринга, тогда как его указатель item$
остался прежним, а для OnPu sh это не означало причин для повторного рендеринга async
.
Поэтому возможные решения:
- вручную, чтобы указать angular, что компонент был обновлен
- , чтобы вызвать изменения, когда компонент стабилен
- , чтобы избежать onPu sh, чтобы angular выполнила глубокую проверку для обнаружения измененного наблюдаемого значения.
вы можете принудительно проверить ngAfterContentInit
родительского компонента после его контент был отрисован, и компонент стабилен.
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent implements AfterContentInit {
constructor(private iService: ItemsService, private cdr: ChangeDetectorRef) { }
item$ = this.iService.item$;
ngAfterContentInit() { // <- add this
this.cdr.detectChanges();
this.cdr.markForCheck();
}
}
Вот демонстрация: https://stackblitz.com/edit/angular-ivy-pxxiee?file=src%2Fapp%2Fcomponents%2Finner%2Finner.component.ts
Если вы не хотите использовать ngAfterContentInit
, тогда вы можете отложить эмиссии, чтобы они были выпущены после всех хуков жизненного цикла.
item$ = this.itemSubject.asObservable().pipe(
delay(0),
);
Вот демонстрация: https://stackblitz.com/edit/angular-ivy-v7upxo?file=src / app / services / items.service.ts