如何在Angular 6组件中映射JSON数据到数组并移除视图管道
我来帮你把模板里的管道逻辑完全迁移到组件类中,同时整理好航班数据方便后续的排序和过滤,一步步来修改代码:
第一步:定义类型接口(可选但强烈推荐)
先给航班数据定义TypeScript接口,避免大量any类型,让代码结构更清晰:
// 单个航班段的结构 interface FlightSegment { departureAirport: string; departureTerminal: string; arrivalAirport: string; arrivalTerminal: string; departureDateTime: string; arrivalDateTime: string; airline: string; flightNumber: string; operatingAirline: string; stops: number; equipment: string; duration: number; } // 完整行程(包含多个中转航班段) interface Itinerary { flightKey: string; flights: FlightSegment[]; priceSummary: { partnerName: string; baseFare: number; totalFare: number; refundStatus: number; }[]; } // API返回的完整响应结构 interface FlightApiResponse { docKey: string; bestPrice: { partnerName: string; baseFare: number; totalFare: number; refundStatus: number; }; onwardFlights: Itinerary[]; }
第二步:修改组件类,处理数据提取、映射与业务逻辑
你原来的循环逻辑存在错误(比如遍历空的data['response']['']),现在我们直接提取API里的核心航班数据,并添加排序、过滤方法:
import { Component, OnInit } from '@angular/core'; import { FlightService } from "../flight.service"; // 把上面的接口定义放在这里 @Component({ selector: 'flight-list', templateUrl: './flight-list.component.html', styleUrls: ['./flight-list.component.css'] }) export class FlightListComponent implements OnInit { // 存储所有完整行程(每个行程包含多个航班段) public itineraries: Itinerary[] = []; // 备份原始数据,用于过滤后恢复 private originalItineraries: Itinerary[] = []; constructor(private svc: FlightService) {} ngOnInit() { this.svc.getFlights().subscribe((data: any) => { // 提取API响应中的核心航班数据 const apiResponse = data.response as FlightApiResponse; this.itineraries = apiResponse.onwardFlights; // 备份原始数据 this.originalItineraries = [...this.itineraries]; // 初始化时可以直接调用排序/过滤方法 this.sortItinerariesByTotalFare(); // 示例:过滤直飞行程 // this.filterItinerariesByMaxStops(0); }); } // 示例:按总价从低到高排序行程 sortItinerariesByTotalFare(): void { this.itineraries.sort((a, b) => { const priceA = a.priceSummary[0]?.totalFare || Infinity; const priceB = b.priceSummary[0]?.totalFare || Infinity; return priceA - priceB; }); } // 示例:按最大中转次数过滤行程 filterItinerariesByMaxStops(maxStops: number): void { // 基于原始数据重新过滤,避免多次过滤导致数据丢失 this.itineraries = this.originalItineraries.filter(itinerary => { // 计算整个行程的总中转次数 const totalStops = itinerary.flights.reduce((sum, segment) => sum + segment.stops, 0); return totalStops <= maxStops; }); } // 重置为原始数据 resetFilters(): void { this.itineraries = [...this.originalItineraries]; } }
第三步:修改模板,移除KeysPipe依赖
现在模板可以直接循环我们在组件里处理好的数组,不需要再用管道:
<!-- 循环每个完整行程 --> <div *ngFor="let itinerary of itineraries; let i = index" class="itinerary-card"> <!-- 循环当前行程的每个航班段 --> <div class="row" *ngFor="let segment of itinerary.flights; let first = first; let last = last;"> <div class="col-md-8 flight-flow-details"> <div class="flight-flow-details-bottom"> <div class="row"> <div class="col-md-5"> <div class="text-light-small-light">{{ segment.departureDateTime }}</div> <div><span class="text-grey"> {{ segment.departureAirport }}</span></div> </div> <div class="col-md-2"> <div class="flight-flow-details-arrow">→</div> </div> <div class="col-md-5"> <div class="text-light-small-light">{{ segment.arrivalDateTime }}</div> <div><span class="text-grey">{{ segment.arrivalAirport }}</span></div> </div> </div> <div class="row"> <div class="col-md-12"> <div class="text-light-small-light pad_top_10"> {{ segment.duration / 60 }} minutes | {{ segment.stops }} stop{{ segment.stops !== 1 ? 's' : '' }} </div> </div> </div> </div> </div> <!-- 中转分隔线(非最后一段时显示) --> <div *ngIf="!last" class="col-md-12 text-center"> <hr class="transfer-divider"> </div> </div> <!-- 行程价格信息 --> <div class="col-md-4 price-info"> <div class="total-fare">₹{{ itinerary.priceSummary[0].totalFare }}</div> <div class="partner-name">via {{ itinerary.priceSummary[0].partnerName }}</div> </div> </div>
关键说明
- 不再依赖
KeysPipe:直接提取API响应里的onwardFlights数组,这才是存储航班行程的核心数据,不需要遍历整个response对象的键。 - 数据可控性更强:所有排序、过滤逻辑都在组件类中实现,方便调试和扩展(比如添加按起飞时间排序、按航空公司过滤等)。
- 原始数据备份:通过
originalItineraries存储原始数据,避免多次过滤后无法恢复初始状态。
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

