Angular 12(TypeScript+Firebase)中如何使用*ngFor遍历数组渲染页面
解决方案
问题根源
你当前的逻辑是直接遍历Firestore返回的文档集合对象,未拿到文档内存储通知数组的字段进行遍历,加上使用了不必要的keyvalue管道,才会导致渲染结果不符合预期。
修复步骤
1. 调整服务层代码
改用snapshotChanges直接格式化返回数据,避免手动遍历处理:
import { Injectable } from '@angular/core'; import { AngularFirestore } from '@angular/fire/compat/firestore'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class NotificacionService { constructor(private firestore: AngularFirestore) {} listarNotificacionSrv3(): Observable<any[]> { return this.firestore.collection('notificacion').snapshotChanges().pipe( map(actions => actions.map(item => { const data = item.payload.doc.data() as any; return { id: item.payload.doc.id, ...data }; })) ); } }
2. 调整组件层代码
额外声明变量接收文档内的通知数组,注意将下方代码里的notificacionList替换为你Firestore文档中实际存数组的字段名:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs'; import { NotificacionService } from './notificacion.service'; @Component({ selector: 'app-notificacion', templateUrl: './notificacion.component.html' }) export class NotificacionComponent implements OnInit, OnDestroy { // 存储集合下所有文档 listarnotificacion2: any[] = []; // 存储待渲染的通知数组 notificacionItems: any[] = []; subscription?: Subscription; constructor(private notificacionService: NotificacionService) {} ngOnInit(): void { this.listarNotificacion2(); } listarNotificacion2() { this.subscription = this.notificacionService .listarNotificacionSrv3() .subscribe(docs => { this.listarnotificacion2 = docs; // 取集合第一个文档内的通知数组,替换成你实际的数组字段名 if (docs.length) { this.notificacionItems = docs[0].notificacionList ?? []; } }); } ngOnDestroy(): void { // 组件销毁时取消订阅避免内存泄漏 this.subscription?.unsubscribe(); } }
3. 调整模板层代码
直接遍历通知数组渲染字段即可,不需要使用keyvalue管道:
<div class="card mt-3" *ngFor="let item of notificacionItems"> <h5>{{ item.title }}</h5> <p>发布时间:{{ item.date | date:'yyyy-MM-dd HH:mm' }}</p> </div>
如果你Firestore的
notificacion集合下每个文档对应一条通知,不存在嵌套数组,直接遍历listarnotificacion2即可,不需要额外声明notificacionItems变量,模板代码调整为:<div class="card mt-3" *ngFor="let doc of listarnotificacion2"> <h5>{{ doc.title }}</h5> <p>发布时间:{{ doc.date | date:'yyyy-MM-dd HH:mm' }}</p> </div>
内容的提问来源于stack exchange,提问作者figueduff
相关产品推荐
相关产品推荐

