Я определяю наблюдаемое (result $) в компоненте и отображаю его в шаблоне через асинхронный канал.Наблюдаемая - это комбинация двух других наблюдаемых (первая $, вторая $) с помощью combLatest.Если одна из наблюдаемых или обе из них выдают слишком рано (до того, как я обнаружил ngAfterContentInit), результирующая наблюдаемая не будет выдавать значение.
Компонент: не работает
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
result$: Observable<number>;
first$ = new Subject<number>();
second$ = new Subject<number>();
constructor() {}
ngOnInit(){
this.result$ = combineLatest(
this.first$,
this.second$
).pipe(
map(([first, second]) => {
// This is not printed to the console
console.log('combined obs emitted value');
return first + second;
})
);
console.log('first and second emit value');
this.first$.next(2);
this.second$.next(4);
}
ngAfterContentInit() {
console.log('ngAfterContentInit');
}
}
Порядок выполнения:
1-е и первое значение излучения
2.ngAfterContentInit
Здесь я предполагаю, что в ngAfterViewInit шаблон был отображен, а подпискибыло сделано.Поскольку наблюдаемые передают значение до этого, компонент не уведомляется.Это может означать только то, что результирующая наблюдаемая является холодной (поэтому вам необходимо подписаться, прежде чем она выдаст значение).2 наблюдаемые являются субъектами, поэтому я предполагаю, что субъекты являются холодными наблюдаемыми.Это правильно?
Если я задерживаю эмиссию первых $ и вторых $, все работает: Component: first $ и second $ emit позже @Component ({selector: 'my-app', templateUrl: './app.component.html ', styleUrls: [' ./app.component.css ']}) класс экспорта AppComponent {
result$: Observable<number>;
first$ = new Subject<number>();
second$ = new Subject<number>();
constructor() {}
ngOnInit(){
this.result$ = combineLatest(
this.first$,
this.second$
).pipe(
map(([first, second]) => {
console.log('combined obs emitted value');
return first + second;
})
);
// Solution 1: add timeout
setTimeout(() => {
console.log('first and second emit value');
this.first$.next(2);
this.second$.next(4);
})
}
ngAfterContentInit() {
console.log('ngAfterContentInit');
}
}
Порядок теперь:
ngAfterContentInit
первое и второе значения излучения
комбинированное значение излучения obs
Такопять же, это потому, что подписка сделана до того, как наблюдаемые передадут значение?
Если я изменю наблюдаемые на BehaviorSubject, все тоже будет работать, даже если значения генерируются до того, как подписка произойдет.Означает ли это, что поведенческие объекты являются горячими наблюдаемыми?Компонент: работает
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
result$: Observable<number>;
first$ = new BehaviorSubject<number>(0);
second$ = new BehaviorSubject<number>(0);
constructor() {
}
ngOnInit(){
this.result$ = combineLatest(
this.first$,
this.second$
).pipe(
map(([first, second]) => {
// This is not printed to the console
console.log('combined obs emitted value');
return first + second;
})
);
console.log('first and second emit value');
this.first$.next(2);
this.second$.next(4);
}
ngAfterContentInit() {
console.log('ngAfterContentInit');
}
}
Stackblitz