如何使用Angular的ngFor指令渲染多层嵌套数组?
Angular模板中递归渲染未知深度的嵌套数据结构
因为你的数据是未知深度的黑盒结构,固定层数的*ngFor没法覆盖所有场景,最佳方案是用递归渲染——要么写一个递归组件,要么用模板递归。
方案一:递归组件(推荐,结构清晰)
创建一个专门处理嵌套项的组件,让它自己调用自己来处理深层结构:
- 生成组件:
ng generate component nested-item
- 组件逻辑(
nested-item.component.ts):
import { Component, Input } from '@angular/core'; @Component({ selector: 'app-nested-item', templateUrl: './nested-item.component.html', styleUrls: ['./nested-item.component.css'] }) export class NestedItemComponent { @Input() item: any; isArray(value: any): boolean { return Array.isArray(value); } isNestedObject(value: any): boolean { return typeof value === 'object' && value !== null && !Array.isArray(value); } getItemName(item: any): string { return item.displayName || item.Name || ''; } }
- 组件模板(
nested-item.component.html):
<div class="nested-item"> <span>{{ getItemName(item) }}: </span> <!-- 渲染原始值 --> <span *ngIf="!isArray(item.value) && !isNestedObject(item.value)"> {{ item.value }} </span> <!-- 处理数组,递归渲染子项 --> <div *ngIf="isArray(item.value)" class="array-container"> <div *ngFor="let subItem of item.value; let i = index"> <span>索引 {{ i }}: </span> <app-nested-item [item]="subItem"></app-nested-item> </div> </div> <!-- 处理嵌套对象,遍历键值对递归渲染 --> <div *ngIf="isNestedObject(item.value)" class="object-container"> <div *ngFor="let key of Object.keys(item.value)"> <app-nested-item [item]="item.value[key]"></app-nested-item> </div> </div> </div>
- 主组件中使用:
假设你的根数据是person,直接传入递归组件即可:
<app-nested-item [item]="person"></app-nested-item>
方案二:模板递归(无需额外组件)
如果不想新建组件,可以用ng-template实现递归渲染:
主组件模板:
<ng-template #renderItem let-item> <div class="nested-item"> <span>{{ item.displayName || item.Name || '' }}: </span> <span *ngIf="!isArray(item.value) && !isNestedObject(item.value)"> {{ item.value }} </span> <!-- 处理数组 --> <div *ngIf="isArray(item.value)" class="array-container"> <div *ngFor="let subItem of item.value; let i = index"> <span>索引 {{ i }}: </span> <ng-container *ngTemplateOutlet="renderItem; context: { $implicit: subItem }"></ng-container> </div> </div> <!-- 处理嵌套对象 --> <div *ngIf="isNestedObject(item.value)" class="object-container"> <div *ngFor="let key of Object.keys(item.value)"> <ng-container *ngTemplateOutlet="renderItem; context: { $implicit: item.value[key] }"></ng-container> </div> </div> </div> </ng-template> <!-- 启动递归渲染 --> <ng-container *ngTemplateOutlet="renderItem; context: { $implicit: person }"></ng-container>
主组件逻辑需添加判断方法:
isArray(value: any): boolean { return Array.isArray(value); } isNestedObject(value: any): boolean { return typeof value === 'object' && value !== null && !Array.isArray(value); }
为什么你原来的代码不行?
你直接用*ngFor="let itemJ of item.value",但item.value可能是字符串(比如Adress2的value是"Perth"),此时*ngFor会把字符串拆成单个字符遍历,完全不符合预期。必须先判断item.value的类型,只有当它是数组或嵌套对象时,才进行遍历递归。
内容的提问来源于stack exchange,提问作者carl
相关产品推荐
相关产品推荐

