问题
我正在使用AngularFire2,并希望返回与两个或多个contactNames相关联的数据。
例如查询我的实时数据库中的contactNames Steve和Brandon:
permits: {
1: {
permit: '12345',
contactName: 'Steve'
},
2: {
permit: '45678',
contactName: 'Brandon'
},
3: {
permit: '78910',
contactName: 'Kevin'
},
4: {
permit: '54321',
contactName: 'Steve'
},
}
回来1: {
permit: '12345',
contactName: 'Steve'
},
2: {
permit: '45678',
contactName: 'Brandon'
},
4: {
permit: '54321',
contactName: 'Steve'
},
我的解决方案尝试
我使用map在数组
中循环并存储可观察对象contactNamesFilter: string[] = ['Steve', 'Brandon'];
const requests = this.contactNamesFilter
.map(contactName => this.permitBrowserService.getData(contactName));
和forkJoin将它们连接到一个可观察对象中。(我使用RxJS v6.6.3)
forkJoin(requests).subscribe(console.log);
问题是订阅forkJoin可观察对象不会返回任何东西。代码似乎已经死亡,没有运行。我知道在所有可观察对象都返回一些东西之前,forkJoin不会返回任何东西。我怀疑这与permitBrowserService.getData()可观察对象在技术上是相同的有关。
我做错了什么?有更好的方法来解决这个问题吗?
其他故障排除
我尝试显式地写出可观察的源,结果相同:
forkJoin({
sourceOne: this.permitBrowserService.getData('Steve'),
sourceTwo: this.permitBrowserService.getData('Brandon'),
}).subscribe(console.log);
备份我正在使用AngularFire2来查询许可证列表:
export class PermitBrowserService {
permitData$: Observable<AngularFireAction<DataSnapshot>[]>;
contactName$: BehaviorSubject<string|null>;
constructor(
public db: AngularFireDatabase,
) {
this.contactName$ = new BehaviorSubject(null);
this.permitData$ = this.contactName$.pipe(
switchMap(contactName =>
db.list('/permits', ref =>
contactName ? ref.orderByChild('contactName').equalTo(contactName) : ref
).snapshotChanges()
)
);
}
getData(contactNameFilter?: string | null): Observable<WellPermit[]> {
if (contactNameFilter) {
this.contactName$.next(contactNameFilter);
}
return this.permitData$.pipe(
map(changes => {
return changes.map(c => {
const data = c.payload.val();
const id = c.key;
return { id, ...data };
})
})
);
}
由于您的this.permitData$
(permitBrowserService.getData())永远不会完成,因此forkJoin将永远不会发出任何东西。因此,使用combinellatest,它将在每次this.permitData$
发射时发射。
combineLatest({
sourceOne: this.permitBrowserService.getData('Steve'),
sourceTwo: this.permitBrowserService.getData('Brandon'),
}).subscribe(console.log);
或
const requests = this.contactNamesFilter
.map(contactName => this.permitBrowserService.getData(contactName));
combineLatest([...requests]).subscribe(console.log);
combineLatest
组合多个Observable来创建一个Observable,它的值为根据每个可观察对象的最新值计算。
forkJoin
接受一个数组的ObservableInput或字典对象ObservableInput并返回一个Observable,该Observable发出一个数组的值,其顺序与传递的数组或字典完全相同与传递的字典形状相同的值。