在Angfirefire2中加入Firebase查询 [英] 'Joining' Firebase Queries in Angularfire2

查看:155
本文介绍了在Angfirefire2中加入Firebase查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:



我遇到的空值字段与我的数据库中不存在的键有关,所以大部分的话语赢得了适用于你的问题。如果您正在寻找一种在AngularFire2中加入查询的方法,那么接受的答案在这方面做得很好。我目前使用 combineLatest 而不是 forkJoin 。为了做到这一点你必须 import'rxjs / add / observable / combineLatest';



以下非规范化的Firebase结构:

$ p $ 成员
-memberid1
-threads
-threadid1: true,
-threadid3:true
-username:Adam
...

线程
-threadid1
- 作者:memberid3
-quality:67
-participants
-memberid2:true,
-memberid3:true
...

我想在 threads中显示 username 视图,按 quality 排序。



我的服务:

  getUsername(memberKey:string){
return this.af.database.object('/ members /'+ memberKey +'/ username')
}

getFeaturedThreads():FirebaseListObservable< any []> {
return this.af.database.list('/ threads',{
query:{
orderByChild:'quality',
endAt:10
}
});





我的组件:

< pre $ ngOnInit(){
this.threads = this.featuredThreadsService.getFeaturedThreads()
this.threads.subscribe(
allThreads =>
allThreads.forEach(thisThread => {
thisThread.username = this.featuredThreadsService.getUsername(thisThread.author)
console.log(thisThread.username)
})

}

由于某些原因,这个日志看起来像是没有实现的可观察对象。





我想要得到这些值到 threads 的属性中,所以我可以像这样在我的视图中渲染它:

 < div * ngFor =let thread of thread | asyncclass =thread-tile> 
...
{{threads.username}}
...
< / div>

更新: console.log for allThreads thisThread







更新:订阅getUsername()

  this.featuredThreadsService.getUsername(thisThread.author)
.subscribe(username => console。日志(用户名))

这个结果是没有值的对象:



您可以编写一个基于 getFeaturedThreads 查询成员的观察值,并将每个线程的参与者属性中的值替换为用户名:


$ b

 从'rxjs / Observable'导入{Observable}; 
导入'rxjs / add / observable / forkJoin';
导入'rxjs / add / operator / do';
导入'rxjs / add / operator / first';
import'rxjs / add / operator / switchMap';

let featuredThreadsWithUserNames = this.getFeaturedThreads()

//每当getFeaturedThreads发出时,切换到取消订阅/忽略
//任何挂起的成员查询:

.switchMap(threads => {

//将线程映射到将被
//加入的观测值数组当observables发出一个值,更新线程

let memberObservables = [];
threads.forEach(thread => {

//添加作者:

memberObservables.push(this.af.database
.object(`members / $ {thread.author}`)
.first()
.do(value => {thread.author = value.username;})
);

//添加参与者:

Object.keys(thread.participants).forEach key => {
memberObservables.push(this.af.database
.object(`members / $ {key}`)
.first()
.do(value => {thread.participants [key] = value.username; })
);
});
});

//加入成员observables,并使用结果选择器
//返回将被更新的线程。

return Observable.forkJoin(... memberObservables,()=> threads);
});

这会给你一个每次发出 getFeaturedThreads 发出。但是,如果用户名称更改,则不会重新发出。如果这很重要,用 combineLatest 来替换 forkJoin ,并移除 first 运算符从组成的成员observables。


Update:

The issues I was encountering with the empty value fields had to do with non-existent keys in my database, so most of the discourse here won't apply to your question. If you're looking for a way to 'join' queries in AngularFire2, the accepted answer below does a fine job of this. I'm currently using combineLatest instead of forkJoin. In order to do this you have to import 'rxjs/add/observable/combineLatest';.

I have the following denormalized Firebase structure:

members
  -memberid1
    -threads
       -threadid1: true,
       -threadid3: true
    -username: "Adam"
    ...

threads
  -threadid1
      -author: memberid3
      -quality: 67
      -participants
         -memberid2: true,
         -memberid3: true
     ...

I want to render username in my threads view, which is sorted by quality.

My service:

getUsername(memberKey: string) {
    return this.af.database.object('/members/' + memberKey + '/username')
}

getFeaturedThreads(): FirebaseListObservable<any[]> {
    return this.af.database.list('/threads', {
        query: {
            orderByChild: 'quality',
            endAt: 10
        }
    });
}

My component:

ngOnInit() {
    this.threads = this.featuredThreadsService.getFeaturedThreads()
    this.threads.subscribe( 
        allThreads => 
        allThreads.forEach(thisThread => {
            thisThread.username = this.featuredThreadsService.getUsername(thisThread.author)
            console.log(thisThread.username)
        })
    )
} 

For some reason this logs what looks like unfulfilled observables to the console.

I'd like to get these values into a property of threads so I can render it in my view like this:

<div *ngFor="let thread of threads | async" class="thread-tile">
    ...
    {{threads.username}}
    ...
</div>

Updated: console.log for allThreads and thisThread

Updated: subscribed to getUsername()

this.featuredThreadsService.getUsername(thisThread.author)
        .subscribe( username => console.log(username))

The result of this is objects with no values:

解决方案

You can compose an observable based on getFeaturedThreads that queries members and replaces the values in each thread's participants property with user names:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/first';
import 'rxjs/add/operator/switchMap';

let featuredThreadsWithUserNames = this.getFeaturedThreads()

  // Each time the getFeaturedThreads emits, switch to unsubscribe/ignore
  // any pending member queries:

  .switchMap(threads => {

    // Map the threads to the array of observables that are to be
    // joined. When the observables emit a value, update the thread.

    let memberObservables = [];
    threads.forEach(thread => {

      // Add the author:

      memberObservables.push(this.af.database
        .object(`members/${thread.author}`)
        .first()
        .do(value => { thread.author = value.username; })
      );

      // Add the participants:

      Object.keys(thread.participants).forEach(key => {
        memberObservables.push(this.af.database
          .object(`members/${key}`)
          .first()
          .do(value => { thread.participants[key] = value.username; })
        );
      });
    });

    // Join the member observables and use the result selector to
    // return the threads - which will have been updated.

    return Observable.forkJoin(...memberObservables, () => threads);
  });

This will give you an observable that emits each time getFeaturedThreads emits. However, if the user names change, it won't re-emit. If that's important, replace forkJoin with combineLatest and remove the first operator from the composed member observables.

这篇关于在Angfirefire2中加入Firebase查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆