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

Angular9动态迭代嵌套JSON数组,解决深层数组DOM渲染位置问题

解决Angular9中嵌套数组的动态迭代渲染问题

我来帮你搞定这个深层数组渲染的问题!你的核心痛点在于没有对嵌套数组做递归处理,同时类型判断的逻辑也有点小问题,导致深层的elementFour数组没法正确展示。下面一步步给你解决:

问题根源分析

  1. 类型判断不准确:你用typeof(val) !== 'object'来判断是否为数组,但JS里数组的typeof结果也是object,而且null的typeof也是object,这会导致判断逻辑出错。
  2. 缺乏递归处理:当前的表格渲染只处理了一层数组,当数组里的元素又是数组时(比如elementFour的值),没有继续递归渲染其内部结构,直接把数组当成普通值显示了。

分步解决方案

1. 修复类型判断方法

把isNotArray改成用Array.isArray()来准确判断数组,同时排除null的干扰:

isNotArray(val: any): boolean {
  return !Array.isArray(val) && val !== null;
}

2. 给表格添加递归渲染逻辑

在<td>里再次判断当前值是否为数组,如果是就递归渲染对应的结构(可以复用你的app-tree-view组件,也可以重复表格逻辑)。修改HTML中的<td>部分:

<td *ngFor="let value of allValues(res.value)">
  <ng-container *ngIf="isNotArray(value); else nestedArray">
    {{value | dataType}}
  </ng-container>
  <ng-template #nestedArray>
    <app-tree-view [(treeData)]="value"></app-tree-view>
    <table border="1">
      <thead>
        <th *ngFor="let nestedKey of allKeys(value);">
          {{nestedKey | sentenceCase}}
        </th>
      </thead>
      <tbody>
        <tr>
          <td *ngFor="let nestedVal of allValues(value)">
            {{nestedVal | dataType}}
          </td>
        </tr>
      </tbody>
    </table>
  </ng-template>
</td>

3. 优化allKeys和allValues方法

让这两个方法能处理嵌套数组的情况,递归提取键和值:

allKeys(value: any[]): string[] {
  return value.map(item => {
    // 如果当前元素是数组,递归提取内部的键
    if (Array.isArray(item)) {
      return this.allKeys(item).join(', ');
    }
    return Object.keys(item)[0];
  });
}

allValues(value: any[]): any[] {
  return value.map(item => {
    if (Array.isArray(item)) {
      return this.allValues(item);
    }
    return Object.values(item)[0];
  });
}

4. 可选:封装递归组件(更优雅)

如果嵌套层级可能更深,建议把数组渲染的逻辑封装成一个独立组件(比如app-nested-renderer),这样在需要递归的地方直接调用组件即可,避免HTML代码重复。

完整修改后的代码示例

app.component.ts

import { Component } from '@angular/core';

const JSON_RESPONSE = { 
  nodeOne: 'string', 
  nodeTwo: new Date(), 
  nodeThree: 123, 
  nodeFour: [ 
    { elementOne: 'string' }, 
    { elementTwo: 456 }, 
    { elementThree: 789 }, 
    { elementFour: [ 
      { elementFive: new Date() }, 
      { elementSix: 101112 } 
    ] } 
  ] 
};

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  response = JSON_RESPONSE;

  isNotArray(val: any): boolean {
    return !Array.isArray(val) && val !== null;
  }

  allKeys(value: any[]): string[] {
    return value.map(item => {
      if (Array.isArray(item)) {
        return this.allKeys(item).join(', ');
      }
      return Object.keys(item)[0];
    });
  }

  allValues(value: any[]): any[] {
    return value.map(item => {
      if (Array.isArray(item)) {
        return this.allValues(item);
      }
      return Object.values(item)[0];
    });
  }

  returnZero() {
    return 0;
  }
}

app.component.html

<div *ngFor="let res of response | keyvalue : returnZero">
  {{res.key | sentenceCase}} : 
  <span *ngIf="isNotArray(res.value); else arrayValues">{{res.value | dataType}}</span>
  <ng-template #arrayValues>
    <app-tree-view [(treeData)]="res.value"></app-tree-view>
    <table border="1">
      <thead>
        <th *ngFor="let key of allKeys(res.value);">
          {{key | sentenceCase}}
        </th>
      </thead>
      <tbody>
        <tr>
          <td *ngFor="let value of allValues(res.value)">
            <ng-container *ngIf="isNotArray(value); else nestedArray">
              {{value | dataType}}
            </ng-container>
            <ng-template #nestedArray>
              <app-tree-view [(treeData)]="value"></app-tree-view>
              <table border="1">
                <thead>
                  <th *ngFor="let nestedKey of allKeys(value);">
                    {{nestedKey | sentenceCase}}
                  </th>
                </thead>
                <tbody>
                  <tr>
                    <td *ngFor="let nestedVal of allValues(value)">
                      {{nestedVal | dataType}}
                    </td>
                  </tr>
                </tbody>
              </table>
            </ng-template>
          </td>
        </tr>
      </tbody>
    </table>
  </ng-template>
</div>

这样修改后,深层的elementFour数组就能正确递归渲染,和你想要的示例图效果一致啦!

内容的提问来源于stack exchange,提问作者Nimish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:12:29