如何在单个 Angular 页面中显示 firebase 多路径信息?
How to display firebase multiple path information in a single Angular page?
我有一个像这样的简单数据库:
{
"groups": {
"123": {
"name": "developers",
"users": {
"1": true
},
"users_count": 1
}
},
"events": {
"456": {
"name": "Developers conference",
"users": {
"1": true
},
"users_count": 1
}
},
"users": {
"1": {
"name": "Jon",
"groups": {
"123": true
},
"events": {
"456": true
}
}
}
}
在用户的主页中,我想显示有关组和事件的所有信息,例如他们的名称。所以,在 Homepage
class 中,我这样做:
获取用户信息后,我查看是否有组或事件。如果是这样,我使用 key
获取每个 key
,subscribe()
到组或事件,并在加载数据后将数据添加到数组中。
export class HomePage {
user: FirebaseObjectObservable<any>;
groupsKey: Array<any>;
groups: Array<any> = [];
eventsKey: Array<any>;
events: Array<any> = [];
constructor(private _auth: AuthService, public afDB: AngularFireDatabase) {
this.user = this.afDB.object(`/users/${this._auth.uid}`);
this.user.subscribe(user =>{
if(user.groups){
this.groupsKey = Object.keys(user.groups);
this.groupsKey.forEach(key => {
let groupObservable = this.afDB.object(`/groups/${key}`);
groupObservable.subscribe(group => {
this.groups.push(group);
})
})
}
if(user.events){
this.eventsKey = Object.keys(user.events);
this.eventsKey.forEach(key => {
let eventObservable = this.afDB.object(`/events/${key}`);
eventObservable.subscribe(event => {
this.events.push(event);
})
})
}
})
}
}
在HTML部分:
<div *ngFor="let item of groups">
{{item.name}}: {{item.users_count}} users
</div>
这种方法乍一看可行,但当在组或事件中进行某些更新时,会将副本推送到数组中,并在重新加载页面时恢复正常。
在这种情况下,什么是更好的实施方式?我知道我应该删除数组并使用 async
管道,但不知道该怎么做。
如果有人偶然发现这个答案与我遇到的问题相同,这是我的解决方案:
我摆脱了静态数组,只使用了 Observables
及其运算符。
export class HomePage {
user: FirebaseObjectObservable<any>;
groups: Observable<Array<{}>>;
events: Observable<Array<{}>>;
constructor(private _auth: AuthService, public afDB: AngularFireDatabase) {
this.user = this.afDB.object(`/users/${this._auth.uid}`);
this.user.subscribe(user =>{
if(user.groups){
this.groups = Observable.of(user.groups)
.map(obj => {
let arr = [];
Object.keys(obj).forEach((key) =>{
//get an Observable containing the info for each key in user.groups object.
arr.push(this.afDB.object(`groups/${key}`));
})
//zip() all Observables in the array
let zip = Observable.zip(...arr);
//return the emitted values (will return an Observable)
return zip;
})
//use switchMap() to flatten the Observables
.switchMap(val => val)
}
if(user.events){
this.events = Observable.of(user.events)
.map(obj => {
let arr = [];
Object.keys(obj).forEach((key) =>{
arr.push(this.afDB.object(`events/${key}`));
})
let zip = Observable.zip(...arr);
return zip;
})
.switchMap(val => val)
}
})
}
}
关于
I know that I should remove the arrays and use the async pipe, but couldn't figure out how to do this.
当我想让页面监听来自数据库的更改时,我就是这样做的。
我像你一样使用 Arrays
- 当我实际上不需要观察时,只是一个列表......
.ts
-----
groupsObservable : Observable<any[]>;
eventsObservable : Observable<any[]>;
loadGroups() {
this.groupsObservable = this.afDB.list("groups/").valueChanges();
}
loadEvents() {
this.eventsObservable = this.afDB.list("events/").valueChanges();
}
.html
------
<div *ngFor="let g of groupsObservable | async">
{{ g.name }}
</div>
<div *ngFor="let e of eventsObservable | async">
{{ e.name }}
</div>
我有一个像这样的简单数据库:
{
"groups": {
"123": {
"name": "developers",
"users": {
"1": true
},
"users_count": 1
}
},
"events": {
"456": {
"name": "Developers conference",
"users": {
"1": true
},
"users_count": 1
}
},
"users": {
"1": {
"name": "Jon",
"groups": {
"123": true
},
"events": {
"456": true
}
}
}
}
在用户的主页中,我想显示有关组和事件的所有信息,例如他们的名称。所以,在 Homepage
class 中,我这样做:
获取用户信息后,我查看是否有组或事件。如果是这样,我使用 key
获取每个 key
,subscribe()
到组或事件,并在加载数据后将数据添加到数组中。
export class HomePage {
user: FirebaseObjectObservable<any>;
groupsKey: Array<any>;
groups: Array<any> = [];
eventsKey: Array<any>;
events: Array<any> = [];
constructor(private _auth: AuthService, public afDB: AngularFireDatabase) {
this.user = this.afDB.object(`/users/${this._auth.uid}`);
this.user.subscribe(user =>{
if(user.groups){
this.groupsKey = Object.keys(user.groups);
this.groupsKey.forEach(key => {
let groupObservable = this.afDB.object(`/groups/${key}`);
groupObservable.subscribe(group => {
this.groups.push(group);
})
})
}
if(user.events){
this.eventsKey = Object.keys(user.events);
this.eventsKey.forEach(key => {
let eventObservable = this.afDB.object(`/events/${key}`);
eventObservable.subscribe(event => {
this.events.push(event);
})
})
}
})
}
}
在HTML部分:
<div *ngFor="let item of groups">
{{item.name}}: {{item.users_count}} users
</div>
这种方法乍一看可行,但当在组或事件中进行某些更新时,会将副本推送到数组中,并在重新加载页面时恢复正常。
在这种情况下,什么是更好的实施方式?我知道我应该删除数组并使用 async
管道,但不知道该怎么做。
如果有人偶然发现这个答案与我遇到的问题相同,这是我的解决方案:
我摆脱了静态数组,只使用了 Observables
及其运算符。
export class HomePage {
user: FirebaseObjectObservable<any>;
groups: Observable<Array<{}>>;
events: Observable<Array<{}>>;
constructor(private _auth: AuthService, public afDB: AngularFireDatabase) {
this.user = this.afDB.object(`/users/${this._auth.uid}`);
this.user.subscribe(user =>{
if(user.groups){
this.groups = Observable.of(user.groups)
.map(obj => {
let arr = [];
Object.keys(obj).forEach((key) =>{
//get an Observable containing the info for each key in user.groups object.
arr.push(this.afDB.object(`groups/${key}`));
})
//zip() all Observables in the array
let zip = Observable.zip(...arr);
//return the emitted values (will return an Observable)
return zip;
})
//use switchMap() to flatten the Observables
.switchMap(val => val)
}
if(user.events){
this.events = Observable.of(user.events)
.map(obj => {
let arr = [];
Object.keys(obj).forEach((key) =>{
arr.push(this.afDB.object(`events/${key}`));
})
let zip = Observable.zip(...arr);
return zip;
})
.switchMap(val => val)
}
})
}
}
关于
I know that I should remove the arrays and use the async pipe, but couldn't figure out how to do this.
当我想让页面监听来自数据库的更改时,我就是这样做的。
我像你一样使用 Arrays
- 当我实际上不需要观察时,只是一个列表......
.ts
-----
groupsObservable : Observable<any[]>;
eventsObservable : Observable<any[]>;
loadGroups() {
this.groupsObservable = this.afDB.list("groups/").valueChanges();
}
loadEvents() {
this.eventsObservable = this.afDB.list("events/").valueChanges();
}
.html
------
<div *ngFor="let g of groupsObservable | async">
{{ g.name }}
</div>
<div *ngFor="let e of eventsObservable | async">
{{ e.name }}
</div>