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
相关产品推荐
相关产品推荐

