如何使用 angulafire2 正确初始化和分配可观察对象?
How do I properly initialize and assign a observable using angulafire2?
我正在使用 Angular 6 和 Rxjs 6。
以下代码将在 ListFormsComponent
处一遍又一遍地抛出 undefined ,直到 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()
returns Observable
到 forms$
时它会破坏 subscriptions
的其余部分。
this.forms$ = new Observable<Array<Forms>>();
所以问题出在这个函数中:
navigateForms() {
this.formService.getForms();
this.navigateService.navigate('forms');
}
您调用了 this.formService.getForms();
,它将在 FormService
上初始化 forms$
。但与此同时,您还导航到 forms
,这将呈现 ListFormsComponent
。在您的 ListFormsComponent
中,您正在执行 formService.forms$
,此时可能尚未初始化。因此你得到它作为 undefined
.
而不是使用 forms$
,我会简单地从 getForms
方法返回 Observable
值,我会在 ListFormComponent
中调用它ngOnInit
方法:
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');
}
我正在使用 Angular 6 和 Rxjs 6。
以下代码将在 ListFormsComponent
处一遍又一遍地抛出 undefined ,直到 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()
returns Observable
到 forms$
时它会破坏 subscriptions
的其余部分。
this.forms$ = new Observable<Array<Forms>>();
所以问题出在这个函数中:
navigateForms() {
this.formService.getForms();
this.navigateService.navigate('forms');
}
您调用了 this.formService.getForms();
,它将在 FormService
上初始化 forms$
。但与此同时,您还导航到 forms
,这将呈现 ListFormsComponent
。在您的 ListFormsComponent
中,您正在执行 formService.forms$
,此时可能尚未初始化。因此你得到它作为 undefined
.
而不是使用 forms$
,我会简单地从 getForms
方法返回 Observable
值,我会在 ListFormComponent
中调用它ngOnInit
方法:
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');
}