Невозможно разделить службу Observable Subject между компонентами внуков в Angular 5

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

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

parent.component.html:

<app-custom-stepper>
<cdk-step [stepControl]="frmStep1" #step1="cdkStep">
<ng-template cdkStepLabel>Step1</ng-template>
    <form #frmStep1="ngForm">
        <child1 [myData]="myData"></child1>
    </form>
    <button cdkStepperPrevious>Prev</button>
    <button cdkStepperNext>Next</button>
</cdk-step>
<cdk-step cdkStep #step2="cdkStep">
    <form #frmStep2="ngForm">
        <child2></child>
    </form>
    <button cdkStepperPrevious>Prev</button>
    <button cdkStepperNext>Next</button>
</cdk-step>

parent.service.ts

export class ParentService {
  myData:Subject<any> = new Subject<any>();

  setMyData(data: any) {
     this.myData.next(data);
  }

  getMyData(): Observable<any> {
     return this.myData.asObservable();
  }
}

child1.component.html:

<sharedGrandchild [myData]="myData"></sharedGrandchild>

child2.component.html

<sharedGrandchild></sharedGrandchild>

grandchild.component.ts:

@Input() myData:MyData;
ngOnInit() {
  if(this.myData) {
    //call service that populates data, this only happens on the page
    //step of the stepper
    this.parentService.setMyData(response);
  } else {
    this.parentService.getMyData()
      .subscribe( myData => {
        this.myData = myData 
      }
   };

Вещи, которые я пробовал:

Использование BehaviorSubjects и Subjects (как в приведенном выше коде) Использование переключателя для задержки инициализации второго дочернего компонента. Попытка использовать другие ловушки жизненного цикла для инициализации подписки для второго дочернего компонента.

Проблема заключается в хронометраже, поэтому запрос на запуск первого дочернего элемента через внука занимает слишком много времени, поэтому возвращаемый внуком второго дочернего элемента подписывается на объект, который присутствует только частично. Это никогда не обновляется. Таким образом, первый дочерний элемент на странице загружается нормально, поскольку он напрямую обращается к службе, а второй дочерний элемент на второй странице степпера содержит неполные данные из-за инициализации в то же время.

1 ответ

Решение

Вы должны выполнить следующие шаги, чтобы обеспечить совместное использование данных в асинхронном режиме.

1.Use BehaviorSubject сохранить последние установленные значения.

   myData:Subject<any> = new BehaviorSubject<any>(null);

2. Прочитайте и установите данные в функции ngAfterViewInit вместо ngOnInit

@Input() myData:MyData;
ngAfterViewInit() {
  if(this.myData) {
    //call service that populates data, this only happens on the page
    //step of the stepper
    this.parentService.setMyData(response);
  } else {
    this.parentService.getMyData()
      .subscribe( myData => {
        this.myData = myData 
      }
   };

3. Убедитесь, что ParentService предоставляется в общем модуле или основном модуле или корневом модуле.

Другие вопросы по тегам