Angular 5+: дочерний компонент, подписанный на наблюдаемый родителем, не получает значения при отображении - PullRequest
2 голосов
/ 27 января 2020

РЕДАКТИРОВАТЬ 2 : Этот является моей общей проблемой и решением (использование setTimeout, чтобы жизненный цикл Angular мог произойти). Я либо закрою это, либо опубликую ответ на свой вопрос, когда смогу.

См. РЕДАКТИРОВАТЬ для более простого воспроизведения, которое не включает Предметы / Наблюдаемые, но по сути является той же проблемой. .

У меня есть родительский компонент, который отвечает за выборку данных из службы.

export class ParentComponent implements OnInit {
  public mySubject: Subject<Foo[]> = new Subject<Foo[]>();
  public buttonClicked = false;
  private currentValues: Foo[] = null;

  constructor(private SomeService myService) { }

  this.myService.get().subscribe(values => {
    this.mySubject.next(values); // Does NOT work when a child component is hidden, as expected.
    this.currentValues = values; // Keep value so we can manually fire later.
  });

  private buttonClickHandler() {
    this.buttonClicked = true;
    this.mySubject.next(this.currentValues);
  }
}

Эти данные подписаны в HTML дочерним компонентом. Этот компонент скрыт по умолчанию через *ngIf и становится видимым только при нажатии кнопки:

<app-child-component [values]="mySubject.asObservable()" *ngif="buttonClicked" />

В родительском компоненте выше вы видите I ' m пытается передать текущие доступные данные дочернему элементу, вызывая next(), когда компонент становится видимым каким-либо образом:

this.mySubject.next(this.currentValues);

Это не работает, когда изначально Отключение компонента с помощью *ngIf. Если я нажму кнопку еще раз, а затем снова вызову next(), она будет работать, как ожидалось Но когда Angular находится в текущем контексте скрытия чего-либо, наблюдаемые не получают свои данные. (Это также происходит, когда что-то скрыто другими средствами, но результат тот же: если в том же методе передача субъекта / данных не работает; компонент уже должен быть виден на момент вызова метода.)

Я предполагаю, что привязка к наблюдаемой не происходит до тех пор, пока *ngIf не покажет дочерний компонент, после разрешения вызова метода. Есть ли место, где я могу подключиться, чтобы потом передать дочерние данные?

РЕДАКТИРОВАТЬ для уточнения : я не думаю, что это проблема Subject против BehaviorSubject. У меня нет проблем с передачей данных. Проблема в том, что передача данных (подтвержденная через console.log()) вообще не происходит вообще. Дело не в том, что дочерний компонент получает значение null. Подписка просто не срабатывает для ребенка.

Я обнаружил, что могу воспроизвести это также более простым способом: попытка выбрать элемент в DOM *ngIf HTML показывает неопределенное, если я сделаю * Значение 1047 * истина в том же методе Angular.

<div *ngIf="buttonClicked">
  <div id="someElement">Foo</div>
</div>
public someMethod(): void {
  this.buttonClicked = true;
  const container = document.getElementById('someElement'); // DOES NOT WORK if this.buttonClicked was false at the start of this method!
}

1 Ответ

0 голосов
/ 27 января 2020

Вам нужно будет использовать BehaviourSubject вместо субъекта, который изначально выдает ранее установленное значение.

В чем разница между субъектом и поведением субъекта?

...