У меня есть компонент, который печатает наблюдаемое значение (test$) в шаблон через асинхронный канал.
Свойство компонента необходимо инициализировать на основе входных данных компонента, поэтому я присваиваю его значение наблюдаемому объекту, испускаемому службой (test$) в ngOnInit. Наблюдаемый, предоставляемый службой, назначается комбинации субъектов при инициализации службы. Значение не печатается в шаблоне. Stackblitz
Если я определяю объединенные темы как BehaviorSubject, шаблон уведомляется о новом значении.
Я предполагаю, что это как-то связано с холодными/горячими наблюдаемыми. Насколько я понимаю, если вы подписываетесь на BehaviorSubject, вы всегда будете получать последнее значение, даже если вы подписались после того, как оно выдало значение, но с холодными наблюдаемыми (как субъект) вам нужно подписаться до того, как значение будет выдано, чтобы получать уведомления .
Так почему же шаблон не обновляется, если подписка происходит до того, как субъекты выдают значение? Я полагаю, что подписка происходит при отображении шаблона, который находится в ngOnInit. Субъекты не излучают свои значения до завершения этого шага.
Компонент
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
@Input() initialValue: number;
result$: Observable<number>;
constructor(private service: TestService) {
}
ngOnInit() {
console.info('component init');
this.result$ = this.service.result$;
// Get data based on inputs
this.service.initTransformedValue(this.initialValue);
}
}
Услуга
@Injectable()
export class TestService {
result$: Observable<number>;
otherValue$: Observable<number>;
transformedValue$: Observable<number>;
constructor() {
console.info('service constructor');
this.init();
}
init(){
this.result$ = combineLatest(
this.transformedValue$,
this.otherValue$
).pipe(map(([first, second]) => {
console.info('have combined value');
return first + second;
})
);
}
initTransformedValue(initialValue) {
// Use timeout to simulate HTTP calls
setTimeout(() => {
console.info('service. emit transformedValue value');
this.transformedValue$ = of(initialValue * 2);
}, 1000);
setTimeout(() => {
console.info('service. emit otherValue value');
this.otherValue$ = of(initialValue * 4);
}, 1200);
}
}
Шаблон
<p>{{result$ | async}}</p>





Вы создаете новую наблюдаемую с помощью of, вам нужно заставить текущую наблюдаемую испускать новое значение.
https://stackblitz.com/edit/angular-fta9h1
Вы никогда не должны переназначать наблюдаемую с другой наблюдаемой, вы должны сделать так, чтобы существующая наблюдаемая испускала, а субъекты и субъекты поведения могли излучать, вызывая next.
const { of, BehaviorSubject } = rxjs;
let obs = of('of initial value');
obs.subscribe(val => { console.info(val); });
// This is a new observable and will not effect the subscription to a different obsevable
obs = of('of new value');
const bs = new BehaviorSubject('BehaviorSubject initial value');
bs.subscribe(val => { console.info(val); });
// This emits a new value on the same observable
bs.next('BehaviorSubject new value');<script src = "https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>
Боже, мне очень жаль, что я случайно перезаписал Stackblitz, и то, что вы говорите, правильно, но не соответствует вопросу (в основном, stackblitz и вопрос не совпадают). Не уверен, что мне следует закрыть этот вопрос и добавить новый?