Тема не запускается при вызове из родительского компонента в ngOnInit

Я использую Rxjs и Angular 7. У меня есть родительский и дочерний компоненты. У меня есть способ вызвать Subject в моем дочернем компоненте:

updateSubject(text: string) {
  this.subject$.next(text);
}

И я вызываю это из своего родительского компонента в ngOnInit, используя ViewChild:

ngOnInit() {
  this.childComponent.updateSubject('New Text');
}

Но subscribe для this.subject$ никогда не срабатывает, если я вызываю его из ngOnInit в родительском компоненте. Если я вызываю метод с помощью кнопки родительского или дочернего элемента, subscribe срабатывает нормально. Что я делаю неправильно?

См. Демонстрацию StackBlitz здесь.


person ViqMontana    schedule 09.07.2019    source источник
comment
Вы, вероятно, подпишетесь после того, как позвоните updateSubject из ngOnInit(). Трудно сказать, если вы не поделитесь всем кодом.   -  person Andrei Tătar    schedule 09.07.2019


Ответы (3)


subscribe() в дочернем элементе вызывается после инициализации родителя. Angular инициализирует компоненты в том же порядке, что и DOM, поэтому сначала инициализируется родительский компонент, а затем инициализируется дочерний компонент.

Subject() отбрасывает выданные значения, если ничего не подписано, и поскольку дочерний элемент подписывается поздно, он не получает значение.

Вы можете использовать BehaviorSubject () или ReplaySubject () в зависимости от того, нужно ли вам начальное значение или нет.

person Reactgular    schedule 09.07.2019
comment
Иногда мне действительно нужно начальное значение, иногда нет. Разве вы не сказали бы, что было бы лучше использовать ловушку жизненного цикла afterViewInit для вызова метода в дочернем компоненте? - person ViqMontana; 09.07.2019
comment
@Viqas afterViewInit требует, чтобы разработчик знал об этом специальном требовании. Откуда им знать? Добавьте документацию или пример. Если они не используют afterViewInit, можно ли сломать ребенка? Для меня не имеет значения, что делает родитель. - person Reactgular; 09.07.2019

Вам нужно использовать ловушку жизненного цикла AfterViewInit. Ваш дочерний компонент еще не был отрисован, когда вызывается OnInit.

Итак, это будет работать:

ngAfterViewInit() {
 this.childComponent.updateSubject('View initialized');
}
person Knelis    schedule 09.07.2019

Используйте BehaviorSubject вместо Subject

subject$: BehaviorSubject<string> = new BehaviorSubject<string>(null);

Ответьте на этот вопрос, чтобы понять разницу между Subject и BehaviorSubject.

Разница между субъектом и поведением

person khush    schedule 09.07.2019