You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Angular的ngFor指令渲染多层嵌套数组?

Angular模板中递归渲染未知深度的嵌套数据结构

因为你的数据是未知深度的黑盒结构,固定层数的*ngFor没法覆盖所有场景,最佳方案是用递归渲染——要么写一个递归组件,要么用模板递归。

方案一:递归组件(推荐,结构清晰)

创建一个专门处理嵌套项的组件,让它自己调用自己来处理深层结构:

  1. 生成组件:
ng generate component nested-item
  1. 组件逻辑(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 || '';
  }
}
  1. 组件模板(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>
  1. 主组件中使用:
    假设你的根数据是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 14:04:57