如何使用angulafire2正确初始化和分配可观察对象?

时间:2018-10-13 19:48:58

标签: angular typescript angularfire2 rxjs6

我正在使用Angular 6和Rxjs 6。

下面的代码将一遍又一遍地在ListFormsComponent上抛出未定义,直到Observable分配了getForms(),然后在该位置显示数据。尝试导航到getForms()页时,导航服务会调用ListFormsComponent

FormService.ts

export class FormService {

  public forms$: Observable <Array<Form>> ;
  public assignedForms$: Observable <Array<Form>> ;
  public form$: Observable <Form>;
  constructor(
    private afs: AngularFirestore,
    private authService: AuthService,
  ) {}

  getForms() {
    let zippedData = zip(this.authService.user$);
    zippedData.subscribe(data => {
      this.forms$ = this.afs.collection('networks')
        .doc(data[0].activeNetworkProfile.id)
        .collection('companyProfiles')
        .doc(data[0].activeCompanyProfile.id)
        .collection<Forms>('inspectionForms')
        .valueChanges();
    })
  }

}

ListFormsComponent.ts

export class ListFormsComponent implements OnInit {
  public forms: Forms[];
  constructor(private formService: FormService, private navigateService: NavigationService) {

    this.formService.forms$.subscribe(forms => { //<---Error here this.formService.forms$ is undefined
      this.forms = forms;
      console.log("Forms inside component");
      console.log(this.forms);
    })
  }
}

ListFormsComponent.html

<mbsc-listview [options]="listSettings" style="display:none">
  <mbsc-listview-item (click)="viewDetails(form.id)" *ngFor="let form of forms">
    <h3 class="mbsc-lv-txt">{{form.name}}</h3>
    <p class="mbsc-lv-txt">{{form.lastEdited | date: 'medium'}} </p>
  </mbsc-listview-item>
</mbsc-listview>

NavigationService.ts

navigateForms() {
  this.formService.getForms();
  this.navigateService.navigate('forms');
}

因此,我随后决定通过在FormService.ts的构造函数中执行以下代码(请参见下文)来初始化可观察的对象,它可以停止错误,但不会触发ListFormsComponent.ts中的订阅。我假设当valueChanges()返回Observableforms$时,它将中断subscriptions的其余部分。

this.forms$ = new Observable<Array<Forms>>();

1 个答案:

答案 0 :(得分:2)

因此问题出在此函数中:

navigateForms() {
  this.formService.getForms();
  this.navigateService.navigate('forms');
}

您调用了this.formService.getForms();,它将在forms$上初始化FormService。但是同时,您还导航到forms,它将呈现ListFormsComponent。在您的ListFormsComponent中,您正在做formService.forms$,这可能还没有初始化。因此,您将其作为undefined

我将只使用forms$方法返回的Observable值,而不是使用getForms,而是在ListFormComponent的{​​{ 1}}方法:

ngOnInit

然后在ListFormsComponent中:

export class FormService {

  public forms$: Observable <Array<Form>> ;
  public assignedForms$: Observable <Array<Form>> ;
  public form$: Observable <Form>;
  constructor(
    private afs: AngularFirestore,
    private authService: AuthService,
  ) {}

  getForms() {
    return zip(this.authService.user$).pipe(
      flatMap(data => {
        return this.afs.collection('networks')
          .doc(data[0].activeNetworkProfile.id)
          .collection('companyProfiles')
          .doc(data[0].activeCompanyProfile.id)
          .collection<Forms>('inspectionForms')
          .valueChanges();
      })
    );
  }

}

而且,我现在不需要从export class ListFormsComponent implements OnInit { public forms: Forms[]; constructor( private formService: FormService, private navigateService: NavigationService ) { } ngOnInit() { this.formService.getForms().subscribe(forms => { this.forms = forms; console.log("Forms inside component"); console.log(this.forms); }); } } 致电getForms。所以我可以摆脱它:

navigateForms