Ionic 3集成Firebase:AngularFire2 v5.0使用及数据查询问题
先来说说你问的第一个问题:
1. 如何用AngularFire2 v5.0关联Firebase数据节点并展示?
假设你的Firebase数据是扁平化设计的(这也是Firebase官方推荐的方式)——比如students节点下每个学生对象里存了对应的classId,而classes节点里用这个classId作为key存班级详情。那可以借助AngularFire2的响应式能力,结合RxJS操作符来关联数据:
首先在你的组件或服务里注入AngularFireDatabase,然后写一个方法来合并学生和班级数据:
import { AngularFireDatabase } from '@angular/fire/database'; import { forkJoin, Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; constructor(private db: AngularFireDatabase) {} getStudentsWithClassDetails(): Observable<any[]> { // 先获取所有学生数据 return this.db.list('students').valueChanges().pipe( map(students => { // 给每个学生创建一个获取对应班级的Observable const classObservables = students.map(student => this.db.object(`classes/${student.classId}`).valueChanges() ); // 用forkJoin等待所有班级数据加载完成,再和学生数据合并 return forkJoin([students, ...classObservables]).pipe( map(results => { const studentList = results[0]; const classList = results.slice(1); // 把每个学生和对应的班级信息合并成新对象 return studentList.map((student, index) => ({ ...student, classData: classList[index] })); }) ); }), switchMap(combinedStream => combinedStream) ); }
然后在组件里订阅这个数据流,配合Angular的async管道在模板里展示:
// 组件里定义Observable studentClassData$: Observable<any[]>; ngOnInit() { this.studentClassData$ = this.getStudentsWithClassDetails(); }
模板代码:
<ion-list> <ion-item *ngFor="let item of studentClassData$ | async"> {{item.name}} of {{item.classData.course}} section {{item.classData.section}} </ion-item> </ion-list>
如果你的数据结构是嵌套式的(比如班级节点下直接嵌套学生),那直接获取班级节点就能拿到关联数据,但还是更推荐扁平化结构,避免数据冗余和查询效率问题。
2. Ionic 3集成Firebase的两个疑问
a) 选Firebase SDK还是AngularFire2 v5.0?
对于你的简易应用来说,AngularFire2 v5.0绝对是更优的选择,原因很实在:
- 它是专门为Angular(Ionic 3基于Angular 5)打造的封装,完美适配Angular的响应式生态,比如RxJS、
async管道,不用手动处理订阅取消,能减少内存泄漏的风险。 - 内置的
AngularFireList、AngularFireObject可以直接和*ngFor配合,代码写起来更简洁,不用自己把Firebase的快照转换成可用的数据格式。 - 原生Firebase SDK虽然灵活,但需要自己做很多适配工作,比如把回调转换成Observable,手动管理订阅,对于简易应用来说完全没必要增加额外的工作量。
当然,如果你的应用后续有非常复杂的自定义需求,原生SDK会更灵活,但目前阶段AngularFire2足够用了。
b) 如何检索学生+班级信息,展示成"suhaib khan of B.tech section B"?
其实这个问题的解决方案就是上面第一个问题里的代码逻辑——先通过classId关联学生和班级数据,然后在模板里把字段拼接成你想要的格式就行。
举个具体的例子,如果你的students节点数据是这样的:
{ "student1": { "name": "suhaib khan", "classId": "class1" } }
classes节点是这样的:
{ "class1": { "course": "B.tech", "section": "B" } }
那用上面的getStudentsWithClassDetails()方法拿到合并后的数据,模板里直接写{{item.name}} of {{item.classData.course}} section {{item.classData.section}},就能输出你想要的格式啦。
内容的提问来源于stack exchange,提问作者MDEez

