从JSON API调用数组实例化对象?

时间:2019-01-21 20:46:36

标签: javascript angular typescript

好的,我在角度6中有一个这样的班级:

export class Game {
 private readonly iD: number;
 private readonly name: string;
 private readonly genre: string;

constructor (iD: number,
        name: string,
        genre: string) {
    this.iD = iD;
    this.name = name;
    this.genre = genre;
}

getName(): string { return this.name }

然后,我进行我的api调用,返回一系列游戏。在一个看起来像这样的类中。

interface ApiGames {
  games: Game[];
}

@Injectable({
 providedIn: 'root'
})
export class GameRepository {
  private game: Game;
  private games: Game[] = [];

constructor(private ApiService: ApiService) {
}

retrieveGames(): void {
this.ApiService.getGames()
  .subscribe(
    (response: ApiGames) => {
      this.games = response.games;
      }
 );
}

getGames(): Game[] { return this.games }

因此,这显然可行,但不会实例化对象。因此,如果在这种情况下(在另一个组件中)调用getter getName()。

<div *ngFor="let game of gameRepository.getGames()">
 {{ game.getName() }}
</div>

它会引发类似TypeError的错误:_v.context。$ implicit.getName()不是函数

但是如果我将实例变量更改为public,是这样的。

<div *ngFor="let game of gameRepository.getGames()">
 {{ game.name }}
</div>

但是我很确定那只行得通,因为我只是在进行类型检查,而没有创建游戏实例……我所做的甚至值得吗?我正在尝试实现更好的实践,并远离过程编程。

1 个答案:

答案 0 :(得分:1)

使用rxjs来传递map,这将直接返回实例数组。

因此您的代码应类似于:

retrieveGames(): void {
  this.ApiService.getGames()
    .pipe(
      map((response: ApiGames) => response.games.map(g => 
        new Game(g.id, g.name, g.genre)
      ))
    )
    .subscribe((games: Game[]) => console.log('games:', games));
}

所以:

  1. 获取游戏
  2. 通过管道传输将api返回的所有数据转换为Game个实例的数组
  3. 现在,在您的订阅中,您直接拥有Game实例中的一系列游戏