Позвольте мне сначала сказать, большой вопрос с деталями и хорошо объяснимым. Вы действительно попали в ловушку обнаружения изменений angular.
Из ngOnChanges
нет прямого способа вызвать другое обнаружение изменений. В противном случае у вас будет возможность поразить всех oop. Кроме того, производительность не позволяет этого. Вам нужно найти способ попасть в следующий цикл выполнения JS
. setTimeout
- неплохой вариант для преодоления этого. Вы можете поместить это вокруг эмиссии:
setTimeout(() => this.secondEmitter.emit(this.first));
или вы можете поместить это вокруг markForCheck
вызова:
setTimeout(() => this.cdRef.markForCheck());
Но я согласен с вами, что это чувствует немного бестолково, но иногда вам просто нужно с этим справиться. Если вы действительно не можете, есть другой способ. Ваш BehaviorSubject
по своей природе является синхронной наблюдаемой. Однако вы можете сделать подписку async
в своем шаблоне, чтобы использовать asyncScheduler
:
private second = new BehaviorSubject(0);
readonly second$ = this.second.asObservable().pipe(
observeOn(asyncScheduler)
)
constructor() {
this.second.next(0);
this.second$.subscribe((lastval) => {
console.log(`second subscription update to ${lastval}`);
});
}
Из последнего варианта, который я сделал, получается ваш стек
.
При этом любая подписка на него получит сообщение после следующего цикла l oop.