TypeScript中如何创建存储不同接口类型子数组的二维数组
解决方法
问题原因
- 第一个问题是异步逻辑顺序错误:你调用的四个服务
getAll()方法都是异步请求,subscribe回调里的赋值操作要等接口请求成功返回后才会执行。而你当前写的this.answer = [this.member,this.publication,this.research,this.course]是同步立即执行的,执行这行代码的时候四个数组还都是初始的空数组,自然拿不到预期数据。 - 第二个问题是
answer变量没有显式声明类型:TypeScript默认无法正确推导包含不同接口类型数组的混合结构,也没法做后续的类型校验。
修复步骤
1. 引入forkJoin操作符
forkJoin可以并行发起多个Observable请求,等所有请求都返回结果后再统一执行回调,正好符合你的需求。
2. 给answer显式声明元组类型
因为你的answer数组长度固定,每个下标的类型固定,用元组类型定义是最合适的,后续取下标对应值的时候可以自动匹配类型。
最终修改代码
import { Component, Input, OnInit } from '@angular/core'; import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { forkJoin } from 'rxjs'; // 引入forkJoin import { MemberService } from 'src/app/services/member.service'; import { Member } from 'src/app/models/member'; import { PublicationService } from 'src/app/services/publication.service'; import { Publication } from 'src/app/models/publication'; import { ResearchService } from 'src/app/services/research.service'; import { Research } from 'src/app/models/research'; import { CourseService } from 'src/app/services/course.service'; import { Course } from 'src/app/models/course'; @Component({ selector: 'app-survey', templateUrl: './survey.component.html', styleUrls: ['./survey.component.scss'] }) export class SurveyComponent implements OnInit { @Input() public renderPage; array1 : string[] = ['member','publication','research','course','event','banner']; // 显式声明answer为元组类型,每个位置对应固定的数组类型 answer: [Member[], Publication[], Research[], Course[]]; ren: Member[] | Publication[] | Research[] | Course[]; member : Member[]=[]; publication :Publication[]=[]; research : Research[]=[]; course : Course[]=[]; constructor( public modal: NgbActiveModal, private ms: MemberService, private ps: PublicationService, private rs: ResearchService, private cs: CourseService) { } ngOnInit(): void { // 用forkJoin并行发起四个请求,等所有请求返回后统一处理 forkJoin({ member: this.ms.getAll(), publication: this.ps.getAll(), research: this.rs.getAll(), course: this.cs.getAll() }).subscribe(res => { // 给四个数组赋值 this.member = res.member.sort((a, b) => a.index - b.index); this.publication = res.publication.sort((a, b) => a.id - b.id); this.research = res.research.sort((a, b) => a.id - b.id); this.course = res.course.sort((a, b) => a.id - b.id); // 这时候四个数组已经有值了,再组装answer this.answer = [this.member, this.publication, this.research, this.course]; // 匹配renderPage赋值ren this.array1.forEach((element, idx) => { if(element === this.renderPage){ this.ren = this.answer[idx]; } }); }) } }
如果不需要保留单独的member/publication等实例变量,还可以简化逻辑,直接从forkJoin返回的结果里组装answer即可。
内容的提问来源于stack exchange,提问作者shinbian11
相关产品推荐
相关产品推荐

