如何加入angularfire2数据库

How to get do a join in angularfire2 database

我已经搜索过了,我仍然找不到正确的答案。我会很高兴你给我指出正确的方向。

我有一个包含用户和项目的数据库

pojects: 
   08177a0acb3f4d96f8cb5fa19002d2ed:
       pid: 08177a0acb3f4d96f8cb5fa19002d2ed,
       pName: "Prject 1"
       uId:  "254",
       createdAt: 9377476



users: 
   254:
       userName: "Eric"
       uId:  "254"
       avatar: "image.jpg"

现在我想显示我的项目,我在我的服务中做了一个列表检索

this.projectList = this.af.database.list('projects',  {
      query: {
        orderByChild: 'createdAt'
      }
    });



getProjects() {
     return this.projectList.map(snapshot => {
         return snapshot;
     });

我订阅了 component.ts

this.projectService.getProjects()
    .subscribe(projects => this.projects = projects);

我想做的是从用户那里获取用户名并将其与项目一起显示。

如何使用项目中的 uId 字段将用户列表中的用户信息检索到一个列表中,以便我可以显示,即 {{project.userName}} {{project.avatar}}?

您可以使用 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;          
      });
  });