首页 文章

Angular Firebase - 将两个Observable合并为一个

提问于
浏览
1

在这里挣扎太久了 . 我在Firebase中有两个表:

accounts
  LJHGGKJH
   prop1: 'val'
   prop2: 'val'
  IUYIUTJF
   prop1: 'val'
   prop2: 'val'

locations_per_account
  LJHGGKJH
   0: [1, 5, 6]
  IUYIUTJF
   0: [5, 2, 8]

正如您所看到 accounts item的唯一关键点 locations_per_account item的唯一键 - 如果它们匹配则属于同一用户 .

现在我想在我的服务中创建一个方法,它可以为我提供每个帐户及其位置的可观察性,因此我可以在模板中使用 async 管道并提取数据 .

在这里,我得到所有帐户:

getAllAccounts() {
    return this.afDb.list('accounts/', {
      query: {
        orderByChild: 'hasAccount',
        equalTo: true
      }
    })      
  }

在这里,我获得特定帐户的位置:

getAccountLocations(optionalUid : string) {
    let uid : any;
    this.authService.authInfo$.subscribe(val => uid = val.$uid); 
    if (typeof optionalUid === 'undefined')
      return this.afDb.object('locations-per-account/' + uid);
    return this.afDb.object('locations-per-account/' + optionalUid);
  }

所以我需要将这些流合并为一个并通过合并我应该构造返回对象的新形状 .

(两个表的顺序是对称的(如果那是正确的单词),但我不确定它将来是否保持不变,所以我想检查两个键是否匹配) .

还要注意 - 如你所见,我可以为每个帐户添加位置数组,但我在单独的表中执行此操作,因为我尝试使Firebase数据库尽可能保持平坦,以避免“全表扫描”之类的操作 . 请提出建议,如果有任何想法 - 我在 Build 数据库方面相当新 .

2 回答

  • 1

    使用forkJoin等待两个查询,然后将两个集合映射到id:

    Rx.Observable.forkJoin([accounts$, locations$]).subscribe(results => {
      const [accounts, locations] = results
      const joined = accounts.map(account => { 
        return {
          id: account.id,
          prop1: account.prop1,
          prop2: account.prop2,
          locations: locations.filter(location => location.id === account.id)[0].loc            };
      })
      console.log(joined);
    });
    

    这假设Firebase为每个查询发出一个值,每个查询都是一个数组(我认为它来自文档) .

    还假定每个id的一个帐户和位置,如果没有,那么映射将需要变得更复杂 .

    这是一个模拟场景的CodePen . CodePen

  • 0

    所以在你的情况下,伪代码可能如下所示:

    Observable.forkJoin([this.getAllAccounts(), this.getAccountLocations()])
       .subscribe(results => {
           console.log(results)
       }
    );
    

    关于管理可观察物的几篇文章:Cory RylanTor

相关问题