Angular 处理多个角度观测值

Angular 处理多个角度观测值,angular,typescript,http,observable,Angular,Typescript,Http,Observable,我是Angular和TypeScript的初学者,因此我正在使用公共口袋妖怪API创建自己的应用程序进行实践。但是,我想得到一些关于使用http获取ID在[1,50]之间的口袋妖怪信息的反馈。要获取每个id的口袋妖怪,我需要一个单独的http get请求。因此,我需要订阅50个可观察对象,然后从所有50个可观察对象的结果中生成一个数组。然而,我想要一些关于是否有更好的方法来实现我希望的目标的建议 poke-dashboard.component.ts(订阅50个可观察对象的代码) 从'@angu

我是Angular和TypeScript的初学者,因此我正在使用公共口袋妖怪API创建自己的应用程序进行实践。但是,我想得到一些关于使用http获取ID在[1,50]之间的口袋妖怪信息的反馈。要获取每个id的口袋妖怪,我需要一个单独的http get请求。因此,我需要订阅50个可观察对象,然后从所有50个可观察对象的结果中生成一个数组。然而,我想要一些关于是否有更好的方法来实现我希望的目标的建议

poke-dashboard.component.ts(订阅50个可观察对象的代码)

从'@angular/core'导入{Component,OnInit};
从“../services/pokemon.service”导入{PokemonService};
从“../shared/Pokemon”导入{Pokemon};
@组成部分({
选择器:“应用程序面板”,
templateUrl:'./poke dashboard.component.html',
样式URL:['./poke dashboard.component.scss'],
})
导出类PokeDashboardComponent实现OnInit{
口袋妖怪:口袋妖怪[];
构造函数(私有pokemonservice:pokemonservice){}
ngOnInit():void{
让口袋妖怪列表:口袋妖怪[]=[];
对于(var i=1;i{
pokemonsList.push(this.pokemonservice.generateKeyon(data));
});
}
this.pokemons=pokemonsList;
}
}
pokemon.service.ts(处理http调用的代码)

从'@angular/core'导入{Injectable};
从“../shared/Pokemon”导入{Pokemon};
从'@angular/common/http'导入{HttpClient};
从“rxjs”导入{Observable};
@注射的({
providedIn:'根',
})
导出类口袋妖怪服务{
baseUrl:字符串;
私人口袋妖怪:口袋妖怪[]=[
新口袋妖怪(
"皮卡丘",,
"皮卡丘",,
90,
50,
50,
40,
55,
35,
'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png'
),
];
构造函数(私有httpClient:httpClient){
此.baseUrl=https://pokeapi.co/api/v2/';
}
公共getPokemonForId(id:number):可观察{
返回this.httpClient.get(this.baseUrl+`pokemon/${id}`);
}
公共生成主题(pokeinfo:any):口袋妖怪{
返回新口袋妖怪(
pokeinfo['name'],
神奇宝贝['species']['name'],
pokeinfo['stats'][0]['base_stat'],
pokeinfo['stats'][1]['base_stat'],
pokeinfo['stats'][2]['base_stat'],
pokeinfo['stats'][3]['base_stat'],
pokeinfo['stats'][4]['base_stat'],
pokeinfo['stats'][5]['base_stat'],
pokeinfo['sprites']['front_default']
);
}
公共口袋妖怪(){
归还这个。口袋妖怪;
}
}

如果您从Angular和RxJS开始学习,我不推荐使用PokeAPI学习。从中获取信息有点复杂

不过,结果中包含了超文本媒体。您可以使用此超文本媒体获取每个ID的URL,而不是使用
for
循环。对URL的GET请求
https://pokeapi.co/api/v2/pokemon/?limit=3&offset=0
获取以下结果

{
  "count": 964,
  "next": "https://pokeapi.co/api/v2/pokemon/?offset=3&limit=3",
  "previous": null,
  "results": [
    {
      "name": "bulbasaur",
      "url": "https://pokeapi.co/api/v2/pokemon/1/"
    },
    {
      "name": "ivysaur",
      "url": "https://pokeapi.co/api/v2/pokemon/2/"
    },
    {
      "name": "venusaur",
      "url": "https://pokeapi.co/api/v2/pokemon/3/"
    }
  ]
}
如果需要前50个条目,可以使用参数
limit=50
发出请求。现在我们可以获取所有URL并发出HTTP请求。我们可以使用RxJS,而不是单独订阅它,它允许我们订阅多个观测值

如果你是从角度开始,它可能有点太多。我要说的是一次做一件事。我建议你从这个开始。它介绍了基本知识

工作示例:

pokemon-api.service.ts

从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpClient,HttpParams};
从“rxjs”导入{of,forkJoin};
从“rxjs/operators”导入{map,catchError,tap};
导出const BASE\u URL='1https://pokeapi.co/api/v2';
@可注射()
出口级PokemonApiService{
构造函数(私有httpClient:httpClient){}
公共GetListofPhokeMon(限制:字符串,偏移量?:字符串){
const params=新的HttpParams()
.set('offset',offset?offset:'0')
.设置(“限制”,限制);
返回此.httpClient
.get(${BASE_URL}/pokemon`,{observe:'response',params:params})
.烟斗(
映射(res=>res.body.results),
catchError(error=>of(error.url))
);
}
公共getPokemonDetails(urlList:Array){
urlList=urlList.map(url=>this.httpClient.get(url));
返回forkJoin(urlList);
}
}
app.component.ts

从'@angular/core'导入{Component};
从'@angular/common/http'导入{HttpClient};
从“rxjs/operators”导入{map,catchError,tap};
从“/pokemon api.service”导入{PokemonApiService};
@组成部分({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent{
口袋妖怪=[];
限额='50';
构造函数(私有的{u pokemonApiService:pokemonApiService){}
恩戈尼尼特(){
this.getPokemonList();
}
私有getPokemonList(){
此._pokemonApiService.getListOfPokemon(this.limit).订阅(
response=>{this.getPokemonDetails(response.map(response=>response.url));},
error=>{console.error(error);}
);
}
私有getPokemonDetails(urlList:Array){
这个._pokemonApiService.getPokemonDetails(urlist).订阅(
response=>{this.pokemons=response;},
error=>{console.error(error);}
);
}
}
app.component.html


身份证件
名称
(传说中的)精灵
{{pokemon.id}}
{{pokemon.name}titlecase}

您能否更具体地说明“更好的方式”的含义?只需要更干净的代码,还是希望一次发送多个请求,或者在收到响应之前限制要发送的请求数?
import { Injectable } from '@angular/core';
import { Pokemon } from '../shared/pokemon';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class PokemonService {
  baseUrl: string;
  private pokemons: Pokemon[] = [
    new Pokemon(
      'pikachu',
      'pikachu',
      90,
      50,
      50,
      40,
      55,
      35,
      'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png'
    ),
  ];
  constructor(private httpClient: HttpClient) {
    this.baseUrl = 'https://pokeapi.co/api/v2/';
  }

  public getPokemonForId(id: number): Observable<any> {
    return this.httpClient.get(this.baseUrl + `pokemon/${id}`);
  }

  public generatePokemon(pokeinfo: any): Pokemon {
    return new Pokemon(
      pokeinfo['name'],
      pokeinfo['species']['name'],
      pokeinfo['stats'][0]['base_stat'],
      pokeinfo['stats'][1]['base_stat'],
      pokeinfo['stats'][2]['base_stat'],
      pokeinfo['stats'][3]['base_stat'],
      pokeinfo['stats'][4]['base_stat'],
      pokeinfo['stats'][5]['base_stat'],
      pokeinfo['sprites']['front_default']
    );
  }

  public getPokemons() {
    return this.pokemons;
  }
}
{
  "count": 964,
  "next": "https://pokeapi.co/api/v2/pokemon/?offset=3&limit=3",
  "previous": null,
  "results": [
    {
      "name": "bulbasaur",
      "url": "https://pokeapi.co/api/v2/pokemon/1/"
    },
    {
      "name": "ivysaur",
      "url": "https://pokeapi.co/api/v2/pokemon/2/"
    },
    {
      "name": "venusaur",
      "url": "https://pokeapi.co/api/v2/pokemon/3/"
    }
  ]
}