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



我正在使用 Angular 6 和 Rxjs 6。

下面的代码将一遍又一遍地在ListFormsComponent抛出 undefined,直到ObservablegetForms()分配,然后它将显示数据。导航服务在尝试导航到ListFormsComponent页面时调用getForms()

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);
})
}
}

列表表单组件.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>

导航服务.ts

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

所以我决定通过在 FormService.ts 的构造函数中执行以下代码(见下文(来初始化可观察量,它会停止错误,但它不会触发ListFormsComponent.ts中的订阅。我假设当valueChanges()Observable返回forms$时,它会破坏subscriptions的其余部分.

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

所以问题出在这个函数上:

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

您已经调用了this.formService.getForms();它将在FormService上初始化forms$。但与此同时,您还将导航到将呈现ListFormsComponentforms。在您的ListFormsComponent中,您正在执行当时可能尚未初始化的formService.forms$。因此,您可以将其视为undefined.

而不是使用forms$,我会简单地从getForms方法返回Observable值,我会在ListFormComponentngOnInit方法中调用它:

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();
})
);
}
}

然后在 ListFormsComponent 中:

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);
});
}
}

另外,我现在不需要从navigateForms打电话给getForms。所以我可以摆脱它:

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

相关内容

最新更新