【发布时间】:2021-07-06 06:51:00
【问题描述】:
我已经被这个问题困扰了几天,只是无法弄清楚出了什么问题。这是应用程序的流程:
调用 API -> 接收响应 -> 在父组件中显示结果 -> 当用户单击结果时,将结果从父级传递给子级。
最后一步是让我头疼的原因,我这辈子似乎无法将嵌套结果从父组件(missionList)传递给我的子组件(misionDetails)
在子组件 HTML 文件中,它会抛出一个错误,提示 “ILinks[]”类型上不存在属性“mission_small_patch”
奇怪的是,如果我只是重新保存我的界面文件,应用程序将重新加载,然后在子组件中显示图像!这让我很困惑,我知道该属性存在并且我相信我可以正确访问它。
我只是不知道我在这里忽略了什么。这可能是我使用自定义管道在父级中显示数据的方式吗?我还尝试更改父级中的 getMission() 方法以映射值 与此类似并且仍然没有变化:
getMission():void{
this.service.subscribe((resp:any)=>{
this.mission_patch_small = resp.map(r => r.links)
})
}
外部 API (https://api.spacexdata.com/v3/launches) 响应给了我一个嵌套对象,我专门针对 links:mission_patch_small
"flight_number": 1,
"mission_name": "FalconSat",
"launch_failure_details": {
"time": 33,
"altitude": null,
"reason": "merlin engine failure"
},
"links": {
"mission_patch": "https://images2.imgbox.com/40/e3/GypSkayF_o.png",
"mission_patch_small": "https://images2.imgbox.com/3c/0e/T8iJcSN3_o.png",
"reddit_campaign": null,
"reddit_launch": null,
"reddit_recovery": null,
"reddit_media": null,
"presskit": null,
"article_link": "https://www.space.com/2196-spacex-inaugural-falcon-1-rocket-lost-launch.html",
"wikipedia": "https://en.wikipedia.org/wiki/DemoSat",
"video_link": "https://www.youtube.com/watch?v=0a_00nJ_Y88",
"youtube_id": "0a_00nJ_Y88",
"flickr_images": []
},
这是我接收数据的界面,你可以看到 我有一个不必要的字段,mission_patch_small,我添加它是为了 调试目的,因为我一生都无法访问此属性!我也尝试将 mission_patch_small 的类型更改为 mission_patch_small : string[] 没有运气。我这样做是为了在上述 getMission() 方法中映射链接 url
export interface IMission {
mission_name: string;
launch_year: string;
details: string;
mission_patch_small: string;
links: ILinks[];
}
export interface ILinks {
mission_patch_small: string[];
}
这是我使用 HttpClient 和 RxJs Observables 获取数据的方式
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { IMission } from '../models/mission';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class SpacexapiService {
baseURL: string = 'https://api.spacexdata.com/v3/launches';
constructor(private http: HttpClient) {}
getMission(): Observable<IMission[]> {
return this.http.get<IMission[]>(this.baseURL);
}
}
这是我的missionList.component.ts 文件
import { Component, OnInit } from '@angular/core';
import { IMission } from '../models/mission';
import { SpacexapiService } from '../network/spacexapi.service';
@Component({
selector: 'app-missionlist',
templateUrl: './missionlist.component.html',
styleUrls: ['./missionlist.component.css'],
})
export class MissionlistComponent implements OnInit {
missionList!: IMission[];
selectedMission!: IMission;
constructor(private service: SpacexapiService) {}
getMission(): void {
this.service.getMission().subscribe((resp: any) => {
this.missionList = resp;
console.log(resp);
});
}
onSelect(mission: IMission): void {
this.selectedMission = mission;
}
ngOnInit(): void {
this.getMission();
}
}
在父组件中显示数据missionList
这是有效的来自links的嵌套数据在这里显示得很好
<ul class="missions"
*ngIf="missionList">
<li *ngFor="let mission of missionList | keys"
(click)="onSelect(mission)"
<span>{{mission.mission_name}}</span> -- {{mission.launch_year}}
<p>{{mission.details}}</p>
<aside><img [src]="mission?.links?.mission_patch_small" /></aside>
</li>
</ul>
<app-missiondetails>[mission]="selectedMission"></app-missiondetails>
密钥管道
export class KeysPipe implements PipeTransform {
transform(value: any, args?: any[]): any {
let keys: any = Object.keys(value),
data: any = [];
keys.forEach((key: any) => {
data.push(value[key]);
});
return data;
}
子组件missionDetails
export class MissiondetailsComponent implements OnInit {
@Input() mission!: IMission;
constructor() {}
ngOnInit(): void {}
}
最后,这是我如何尝试在孩子身上显示数据以及我收到错误的位置。
<ul *ngIf="mission">
<li><span>{{mission.mission_name}}</span> {{mission.launch_year}}
<p>{{mission.details}}</p>
<p>{{mission.links | json}}</p>
<aside><img [src]="mission?.links?.mission_small_patch" /></aside>
</li>
</ul>
【问题讨论】:
-
我会调查
onSelect方法和keys管道。 -
在您的服务文件中,您应该尝试将结果作为像
return this.http.get<IMission[]>(this.baseURL) as Observable<IMission[]>;这样的 observable 返回,看看是否有帮助。
标签: javascript angular typescript api rxjs