firebase - 展平/链接多个嵌套的 firebase Observables

标签 firebase firebase-realtime-database observable rxjs5 angularfire2

我正在尝试使用 AngularFire2。我正在查询,下面一切正常。

我想将所有/大部分可观察值合并为一个:

getTournamentWithRounds(key):Observable<Tournament> {

    return this.af.database
        .object(`/tournaments/${key}`)
        .map(tourney => {

            let t = Tournament.fromJson(tourney);

            this.af.database.list('players', {
                query: {
                    orderByChild: 'tournament_key',
                    equalTo: key
                }
            })
            .map(Player.fromJsonList)
            .subscribe(ps => { t.players = ps; });

            this.af.database.list('rounds', {
                query: {
                    orderByChild: 'tournament_key',
                    equalTo: key
                }
            })
            .map(Round.fromJsonList)
            .subscribe(rs => { t.rounds= rs; })

            return t;
        })
  }

我想知道是否可以加入所有可观察量并使用单个订阅函数获取输出。

我想知道所有初始数据何时已加载,并在将其输出到 View 之前在 Controller 中执行额外的计算。

此外,如何扩展到包括每轮的比赛?

我对上述代码的扩展是:

...

this.af.database.list('rounds', {
    query: {
        orderByChild: 'tournament_key',
        equalTo: key
    }
})
.map(rounds => {
    return rounds.map((round) => {

        let r = Round.fromJson(round);

        this.af.database.list('matches', {
            query: {
                orderByChild: 'round_key',
                equalTo: round.$key
            }
        })
        .map(Match.fromJsonList)
        .subscribe(matches => { r.matches = matches; })

        return r;
    })
})
.subscribe(rs => { t.rounds= rs; })

...

最佳答案

您可以使用 combineLatest 运算符将玩家和回合与锦标赛结合起来:

getTournamentWithRounds(key): Observable<Tournament> {

  return this.af.database
    .object(`/tournaments/${key}`)
    .combineLatest(
      this.af.database.list('players', {
        query: {
          orderByChild:'tournament_key',
          equalTo: key
        }
      }),
      this.af.database.list('rounds', {
        query: {
          orderByChild:'tournament_key',
          equalTo: key
        }
      })
    )
    .map(([tourney, players, rounds]) => {

      let t = Tournament.fromJson(tourney);
      t.players = Player.fromJsonList(players);
      t.rounds = Round.fromJsonList(rounds);
      return t;
    });
}

每当任何可观察量发出时,最新值都会重新组合,并发出新的锦标赛

将其扩展为包括每轮的比赛有点复杂,因为匹配查询需要每轮的 key 。

发出的回合可以映射到匹配的可观察列表数组,并且可以使用 forkJoin 来连接可观察,并使用 forkJoin 选择器函数来将比赛与回合结合起来。然后使用 switchMap 来发射子弹。

getTournamentWithRounds(key): Observable<Tournament> {

  return this.af.database
    .object(`/tournaments/${key}`)
    .combineLatest(
      this.af.database.list('players', {
        query: {
          orderByChild:'tournament_key',
          equalTo: key
        }
      }),
      this.af.database.list('rounds', {
        query: {
          orderByChild:'tournament_key',
          equalTo: key
        }
      })
      .switchMap(rounds => {
        Observable.forkJoin(
          rounds.map(round => this.af.database.list('matches', {
            query: {
              orderByChild: 'round_key',
              equalTo: round.$key
            }
          }).first()),
          (...lists) => rounds.map((round, index) => {
            let r = Round.fromJson(round);
            r.matches = Match.fromJsonList(lists[index]);
            return r;
          })
        )
      })
    )
    .map(([tourney, players, rounds]) => {

      let t = Tournament.fromJson(tourney);
      t.players = Player.fromJsonList(players);
      t.rounds = rounds;
      return t;
    });
}

关于firebase - 展平/链接多个嵌套的 firebase Observables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40536152/

相关文章:

javascript - 检索 firebase 中所有用户的所有数据

javascript - Cloud Function 无法访问 Firebase 数据库

ios - Firebase - 使用 'Node-Id' 检索节点

angular - 在 Angular 中链接可观察对象的最佳方法是什么?

angularjs - 如何在 Angularjs2 中设置初始可观察值?

c# - 我如何创建一个 Rx observable 来获取立即值然后采样?

swift - 在Swift中安装 'Firebase/Crashlytics' Pod时出错

javascript - 基于 React 中的 Promise 呈现元素(Firebase 存储)

java - 如何在 firebase 中添加计数器?

ios - 将 firebase 图像放入数组中