Angular中*ngFor失效,无法从Firebase获取三级子节点数据
嘿,咱们来逐个解决你在Angular开发中遇到的这两个问题!
问题1:*ngFor指令无法正常工作
先从最常见的排查方向入手:
- 确认绑定的变量是数组类型:*ngFor只能遍历数组,如果你的
date是对象、undefined或者null,肯定不会渲染任何内容。可以在组件的subscribe回调里加个日志:console.log(Array.isArray(this.date)),验证下数据类型是否正确。 - 处理异步数据的时机:因为你是从Firebase异步获取数据,手动subscribe可能会出现数据还没返回就渲染模板的情况。更稳妥的方式是用Angular的
async管道,直接在模板中处理Observable:
对应的组件代码不用手动subscribe,直接把Observable赋值给变量:<!-- 模板代码 --> <div *ngFor="let item of date$ | async"> <!-- 渲染你的数据 --> </div>
这样Angular会自动帮你管理订阅和数据更新,避免时序问题。// 组件代码 date$: Observable<any[]>; ngOnInit() { this.id = this.route.snapshot.paramMap.get('id'); if(this.id) { this.date$ = this.scheduleService.get(this.id); } } - 检查模板语法细节:有没有拼写错误?比如把
*ngFor写成*ngfor(注意F是大写);或者循环变量名和模板中其他变量冲突?另外如果数组为空,可以加个空状态提示:<div *ngIf="(date$ | async)?.length === 0">暂无数据</div> <div *ngFor="let item of date$ | async">...</div> - 确认组件变量是公共属性:如果
date被定义成private date,模板是无法访问到的,需要改成public date或者省略访问修饰符(Angular组件属性默认是public)。
问题2:获取Firebase三级子节点的数据
从你提供的代码片段来看,推测你的Firebase数据结构是三级嵌套(比如date -> [id] -> [三级子节点]),要获取指定id下的三级子节点数据,需要调整服务中的查询逻辑:
假设你的Firebase数据结构如下:
date ├─ {你的id} │ ├─ {三级子节点key1} │ │ ├─ field1: "xxx" │ │ └─ field2: "xxx" │ └─ {三级子节点key2} │ ├─ field1: "yyy" │ └─ field2: "yyy" └─ ...
调整服务端的get方法:
如果是AngularFire2的旧版本(v6及以下),可以这样写:
// 服务代码 import 'rxjs/add/operator/map'; get(id: string) { // 指向指定id下的二级节点(也就是三级子节点的父节点) return this.db.list(`date/${id}`).snapshotChanges().map(actions => { return actions.map(action => { // 把Firebase节点的key和数据合并,方便模板使用 const data = action.payload.val(); const key = action.payload.key; return { key, ...data }; }); }); }
如果是AngularFire v7+的新版本,API有所调整,需要用rxjs的pipe和map操作符:
// 服务代码 import { map } from 'rxjs/operators'; get(id: string) { return this.db.list(`date/${id}`).snapshotChanges().pipe( map(actions => actions.map(action => ({ key: action.key, ...action.payload.val() })) ) ); }
调整后,组件中订阅获取到的this.date就是三级子节点的数组,配合上面*ngFor的正确用法,就能正常渲染数据了。
如果还是有问题,可以把你的模板代码或者console.log(this.date)的输出结果贴出来,方便进一步排查!
内容的提问来源于stack exchange,提问作者Jim Williams
相关产品推荐
相关产品推荐

