已解析的Promise中的数据未在组件视图中正确加载(Angular2,JavaScript)

时间:2017-04-22 19:29:31

标签: javascript angular es6-promise

我是Angular2的新手,请原谅我,如果这是一个超级基本修复。

我正在使用tutorial using PokeAPI and Angular2,但试图偏离教程,将Pokemon类型添加到渲染视图中。但是,我的PokedexService中的数据没有正确加载到我的视图模板中。

Github上产生错误的完整代码库。

由于它偏离了原始教程,我更新了Pokemon类以向其添加types属性:

export class Pokemon {
  id: number;
  sprite: string;
  name: string;
  types: [];
}

在我的pokedex.service.ts服务文件中,我添加了一个新方法getPokemonTypes(),用于查询每个Pokemon类型的API,并返回包含一种或两种类型的数组。

getPokemonTypes(id: number): Promise<any> {
    return this.http.get(`${this.baseUrl}${id}/`)
    .toPromise()
    .then(response => response.json())
    .then(details => {
      const types = details.types
      .map(t => {
        return t.type.name;
      });
      return types;
    });
}

在我的app.component.ts中,我在loadMore()中调用了一种方法ngOnInit应该加载渲染视图所需的所有数据应用初始化。在loadMore()方法中,我调用了pokedexService的{​​{1}}方法,然后在Promise的解析链中,我调用getPokemon()将Pokemon类型值映射到我的口袋妖怪对象。

getPokemonTypes()

在我的视图模板(export class AppComponent implements OnInit { pokemon: Pokemon[] = []; isLoading: boolean = false; error: boolean = false; constructor(private pokedexService: PokedexService) { } ngOnInit() { this.loadMore(); } loadMore() { this.isLoading = true; this.pokedexService.getPokemon(this.pokemon.length, 9) .then(pokemon => { pokemon = pokemon.map(p => { p.imageLoaded = false; // Map Pokemon types onto each Pokemon object p.types = this.pokedexService.getPokemonTypes(p.id); return p; }); this.pokemon = this.pokemon.concat(pokemon); this.isLoading = false; this.error = false; }) .catch(() => { this.error = true; this.isLoading = false; }) } } )中,我添加了app.component.html来保存Pokemon类型。目前,div仅通过<div>呈现,以便我可以获得有关导致错误的原因的反馈。作为参考,这是视图模板:

{{p.types}}

当我重新加载应用时,视图呈现如下: Pokedex App -- Error1 其中,它不显示类型,而是显示<div class="pokedex"> <div class="pokedex-pokemon" *ngFor="let p of pokemon"> <div class="pokedex=pokemon-id"> #{{p.id}} </div> <img [ngClass]="{'hidden': !p.imageLoaded}" class="pokedex-pokemon-sprite" (load)="p.imageLoaded = true" [attr.src]="p.sprite" /> <div class="pokedex-pokemon-name"> {{p.name | capitalize}} </div> <div class="pokedex-pokemon-types" *ngIf="!isLoading"> {{p.types}} </div> </div> </div> 。我也尝试使用[object Promise]渲染视图,因为Pokemon.types是一个类型数组,但是当我这样做时,它不会在视图中呈现任何内容: Pokedex App -- Error2

我假设我以某种方式需要解析存储在{{p.types[0]}}{{p.types[1]}}属性中的Promise,但我想在PokedexService的types方法中对返回的HTTP promise承担.then()解决了对我有价值的承诺。

作为旁注,我最终想在我的视图中渲染类型:

getPokemonTypes()

但到目前为止,我还没能得到它。我不完全确定<div class="pokedex-pokemon-types"> <div *ngFor="let t of pokemon.types"> <div [ngClass]="${t}">{{t}}</div> </div> </div> 指令的正确语法是什么让它使用Pokemon类型名称作为每个div的类。

感谢您提供的任何帮助!非常感谢。

1 个答案:

答案 0 :(得分:1)

结果this.pokedexService.getPokemonTypes(p.id)不是一个承诺吗?如果是,我认为你应该写这样的东西:

pokemon = pokemon.map(p => {
  p.imageLoaded = false;

    this.pokedexService.getPokemonTypes(p.id)
    .then(types => {
      p.types = types;
      this.pokemon = this.pokemon.concat(p);
      this.isLoading = false;
      this.error = false;      
    });
  });