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

Angular5:将嵌套对象转换为嵌套数组以用于ngFor

在Angular 5中将嵌套对象转换为适配ngFor的嵌套数组

嘿,我来帮你理清楚这个问题。其实你的原始数据已经包含了适合ngFor指令的数组结构,但如果要把嵌套对象转换成更规整的嵌套数组(比如统一数组格式,方便多层遍历),这里有几种实用的方案,完全适配Angular 5的场景:

方案一:直接利用现有数组结构(最简单)

你的data本身就是顶层数组,里面每个甜甜圈对象的batters.batter和topping也都是数组——其实不需要额外转换,直接在模板里嵌套ngFor就行。

组件代码(只需引入原始数据)

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

@Component({
  selector: 'app-donut-view',
  templateUrl: './donut-view.component.html'
})
export class DonutViewComponent {
  donuts = [
    {
      "id": "0001",
      "type": "donut",
      "name": "Cake",
      "ppu": 0.55,
      "batters": {
        "batter": [
          { "id": "1001", "type": "Regular" },
          { "id": "1002", "type": "Chocolate" },
          { "id": "1003", "type": "Blueberry" },
          { "id": "1004", "type": "Devil's Food" }
        ]
      },
      "topping": [
        { "id": "5001", "type": "None" },
        { "id": "5002", "type": "Glazed" },
        { "id": "5005", "type": "Sugar" },
        { "id": "5007", "type": "Powdered Sugar" },
        { "id": "5006", "type": "Chocolate with Sprinkl..." }
      ]
    }
  ];
}

模板代码(多层ngFor直接遍历)

<!-- 遍历顶层甜甜圈数组 -->
<div *ngFor="let donut of donuts" class="donut-card">
  <h3>{{ donut.name }} (ID: {{ donut.id }})</h3>
  <p>单价: ${{ donut.ppu }}</p>

  <!-- 遍历面糊数组(注意是batters.batter,因为batters是对象,batter才是数组) -->
  <div class="section">
    <h4>可选面糊:</h4>
    <ul>
      <li *ngFor="let batter of donut.batters.batter">
        {{ batter.type }} (ID: {{ batter.id }})
      </li>
    </ul>
  </div>

  <!-- 遍历顶料数组 -->
  <div class="section">
    <h4>可选顶料:</h4>
    <ul>
      <li *ngFor="let topping of donut.topping">
        {{ topping.type }} (ID: {{ topping.id }})
      </li>
    </ul>
  </div>
</div>

方案二:将嵌套对象转换为通用嵌套数组(适合复杂场景)

如果未来你的batters对象可能包含多个属性(不止batter一个),或者你希望统一用数组格式处理所有嵌套结构,可以用Object.entries()把对象转换为键值对数组,再整理成更易读的结构。

组件代码(处理数据为嵌套数组)

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

@Component({
  selector: 'app-donut-view',
  templateUrl: './donut-view.component.html'
})
export class DonutViewComponent {
  originalDonuts = [/* 你的原始数据 */];
  
  // 转换为通用嵌套数组结构
  formattedDonuts = this.originalDonuts.map(donut => ({
    basicInfo: Object.entries(donut)
      // 过滤掉已经是数组的属性
      .filter(([key]) => !['batters', 'topping'].includes(key))
      .map(([label, value]) => ({ label, value })),
    // 把batters对象转成数组,每个项包含分类名和对应的面糊数组
    batters: Object.entries(donut.batters).map(([category, items]) => ({
      category,
      items: items.map(item => Object.entries(item).map(([k, v]) => ({ label: k, value: v })))
    })),
    // 把topping数组也转成统一的键值对数组格式
    toppings: donut.topping.map(item => Object.entries(item).map(([k, v]) => ({ label: k, value: v })))
  }));
}

模板代码(遍历统一的嵌套数组)

<div *ngFor="let donut of formattedDonuts" class="donut-card">
  <!-- 遍历基础信息数组 -->
  <div class="basic-info">
    <h3>甜甜圈信息</h3>
    <p *ngFor="let info of donut.basicInfo">
      {{ info.label }}: {{ info.value }}
    </p>
  </div>

  <!-- 遍历面糊分类数组 -->
  <div class="section">
    <h4>面糊选项</h4>
    <div *ngFor="let batterGroup of donut.batters">
      <p>{{ batterGroup.category }}:</p>
      <ul>
        <li *ngFor="let batter of batterGroup.items">
          <span *ngFor="let prop of batter">
            {{ prop.label }}: {{ prop.value }}
          </span>
        </li>
      </ul>
    </div>
  </div>

  <!-- 遍历顶料数组 -->
  <div class="section">
    <h4>顶料选项</h4>
    <ul>
      <li *ngFor="let topping of donut.toppings">
        <span *ngFor="let prop of topping">
          {{ prop.label }}: {{ prop.value }}
        </span>
      </li>
    </ul>
  </div>
</div>

关键说明

  • Angular 5的ngFor只要求遍历目标是数组或类数组对象,所以如果原始数据里已经有数组,直接用最省事儿。
  • Object.entries()是ES2017的API,Angular 5默认支持(因为用了TypeScript编译),它能把对象的每个键值对转换成[key, value]的数组,非常适合把对象转成可遍历的数组结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:36:20