我搜索过,但仍然无法得到正确答案。我很高兴你指出了正确的方向。
我有一个包含用户和项目的数据库
function potato(param) {
document.body.style.backgroundImage = 'url(file:///C:/Users/Joe)';}
现在我要显示我的项目,我在服务中执行列表检索
pojects:
08177a0acb3f4d96f8cb5fa19002d2ed:
pid: 08177a0acb3f4d96f8cb5fa19002d2ed,
pName: "Prject 1"
uId: "254",
createdAt: 9377476
users:
254:
userName: "Eric"
uId: "254"
avatar: "image.jpg"
我订阅了component.ts
this.projectList = this.af.database.list('projects', {
query: {
orderByChild: 'createdAt'
}
});
getProjects() {
return this.projectList.map(snapshot => {
return snapshot;
});
我想要做的是从用户那里获取userName并将其与项目一起显示。
如何在项目中使用uId字段将用户列表中的用户信息检索到一个列表中,以便显示this.projectService.getProjects()
.subscribe(projects => this.projects = projects);
?
答案 0 :(得分:8)
您可以使用forkJoin
获取项目的用户,并可以使用其结果选择器将所需的属性复制到发出的项目对象中:
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/first';
import 'rxjs/add/operator/switchMap';
// Compose an observable based on the projectList:
this.projectWithUserList = this.projectList
// Each time the projectList emits, switch to unsubscribe/ignore
// any pending user queries:
.switchMap(projects => {
// Map the projects to the array of observables that are to be
// joined.
let userObservables = projects.map(project => this.af.database
.object(`users/${project.uId}`)
.first()
);
// Join the user observables, and match up the users with the
// projects, etc.
return userObservables.length === 0 ?
Observable.of(projects) :
Observable.forkJoin(...userObservables, (...users) => {
projects.forEach((project, index) => {
project.userName = users[index].userName;
project.avatar = users[index].avatar;
});
return projects;
})
});
只要数据库中的项目发生更改,上述实现就会发出一系列项目,但如果用户信息发生更改,它将不会发出数组。
如果要在项目或用户信息发生变化时发出数组,则可以为用户使用combineLatest
代替forkJoin
:
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/combineLatest';
import 'rxjs/add/operator/switchMap';
// Compose an observable based on the projectList:
this.projectWithUserList = this.projectList
// Each time the projectList emits, switch to unsubscribe/ignore
// any pending user queries:
.switchMap(projects => {
// Map the projects to the array of observables that are to be
// combined.
let userObservables = projects.map(project => this.af.database
.object(`users/${project.uId}`)
);
// Combine the user observables, and match up the users with the
// projects, etc.
return userObservables.length === 0 ?
Observable.of(projects) :
Observable.combineLatest(...userObservables, (...users) => {
projects.forEach((project, index) => {
project.userName = users[index].userName;
project.avatar = users[index].avatar;
});
return projects;
});
});