首页 > 解决方案 > Angular 11,子组件未从父组件接收嵌套 API 对象

问题描述

我已经被这个问题困住了几天,只是无法弄清楚出了什么问题。这是应用程序的流程:

调用 API -> 接收响应 -> 在父组件中显示结果 -> 当用户单击结果时,将结果从父组件传递给子组件。

最后一步是让我头疼的原因,我这辈子似乎无法将嵌套结果从我的父组件(任务列表)传递给我的子组件(任务详情

在子组件 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 ) 响应给了我一个嵌套对象,我专门针对链接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();
  }
}

在父组件任务列表中显示数据

这是有效的链接中的嵌套数据在这里显示得很好

<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;
  }

子组件任务详情


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>


标签: javascriptangulartypescriptapirxjs

解决方案


您需要更多地研究您返回的对象,请考虑以下提取...

"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": []
    },

在您的界面中,您已经声明links: ILinks[];暗示链接是一个数组,不幸的是,您的对象links是一个对象。

因此,解决问题的第一步是将其更改为links: ILinks;

接下来要注意的是您的属性的名称...

在您的界面中,您定义mission_small_patch但您调用的属性mission_patch_small。对齐这个可以解决你的问题

看到这个链接


推荐阅读