在Angfirefire2中加入Firebase查询 [英] 'Joining' Firebase Queries in Angularfire2
问题描述
更新:
我遇到的空值字段与我的数据库中不存在的键有关,所以大部分的话语赢得了适用于你的问题。如果您正在寻找一种在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
我的服务:
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屋!