Angular NG0900错误:NgFor仅支持可迭代对象,修复后遇TS2769问题
问题解决:Angular NgFor NG0900 及 TypeScript 类型错误
问题根源
- NG0900错误:Firebase Realtime Database 返回的是键值对对象(形如
{ "id1": {...}, "id2": {...} }),但*ngFor仅支持遍历数组/可迭代对象,直接将对象赋值给equipo数组会触发该错误。 - TypeScript类型错误:
HttpClient.get()默认返回Object类型,你直接指定订阅参数为any[]会导致类型不匹配,触发TS编译错误。
解决方案
1. 将Firebase返回的对象转为数组
使用Object.values()方法提取对象中的值,转换为数组后赋值给equipo。同时给http.get()指定泛型,解决类型不兼容问题:
修改服务中的cargarEquipo方法:
private cargarEquipo() { // 指定泛型为any,明确返回数据类型 this.http.get<any>("https://pratice-fe972-default-rtdb.firebaseio.com/.json") .subscribe(resp => { // 将对象转为数组 this.equipo = Object.values(resp); console.log(this.equipo); }); }
2. (可选)更规范的类型定义
如果希望类型更严谨,可以先定义人员数据的接口:
// 在服务文件或单独的interface文件中定义 export interface Persona { nombre: string; subtitulo: string; frase: string; twitter: string; url: string; }
然后修改服务中的equipo类型和请求泛型:
// 服务类中 equipo: Persona[] = []; private cargarEquipo() { // 泛型指定为键值对结构,值为Persona类型 this.http.get<{ [key: string]: Persona }>("https://pratice-fe972-default-rtdb.firebaseio.com/.json") .subscribe(resp => { this.equipo = Object.values(resp); console.log(this.equipo); }); }
3. 优化:添加加载状态避免异步问题
因为HTTP请求是异步的,可在服务中添加加载状态,避免模板在数据未返回时出现异常:
// 服务类中添加状态 equipoCargado: boolean = false; private cargarEquipo() { this.http.get<{ [key: string]: Persona }>("https://pratice-fe972-default-rtdb.firebaseio.com/.json") .subscribe(resp => { this.equipo = Object.values(resp); this.equipoCargado = true; // 标记数据加载完成 }); }
模板中添加加载判断:
<div *ngIf="infoService.equipoCargado; else loading"> <div *ngFor="let persona of infoService.equipo" class="animate__animated animate__bounce ae-grid__item item-lg-4 ae-kappa au-mb-3"> <img [src]="persona.url" alt="" class="au-mb-3"> <h5 class="ae-u-bolder au-mt-2">{{ persona.nombre }}</h5> <p class="ae-u-bolder au-mb-3">{{ persona.subtitulo }}</p> <p class="au-lg-ta-left au-mb-3 au-pl-4 au-pr-4">{{ persona.frase }}</p> <a target="_blank" href="http://www.twitter.com/{{ persona.twitter }}" class="ae-u-bolder au-underline">{{ persona.twitter }}</a> </div> </div> <ng-template #loading> <p>团队数据加载中...</p> </ng-template>
内容的提问来源于stack exchange,提问作者carlo1023
相关产品推荐
相关产品推荐

