我有一个组件,该组件使用服务从API获取数据。该服务和组件可以正常工作,因为我可以在表格的页面上成功显示此数据。我现在尝试在另一个组件内部使用此组件来填充下拉表单控件。不幸的是,此下拉列表并未填充。
调试时,这看起来像是一个异步问题,因为我可以看到控制台中正在显示数据(使用console.log()
进行调试)。我还可以看到在显示之前和之后放置的其他console.log()
语句,但是都在调用嵌套组件之前在之前输出它们的值。
呼叫组件
ngOnInit() {
// Debugging code
console.log('Before this.playerComponent.getPlayers()');
// Nested component that gets the data from a service
this.playerComponent.getPlayers();
this.players = this.playerComponent.players;
// Debugging code
console.log('After this.playerComponent.getPlayers()');
}
PlayerComponent(嵌套组件)
getPlayers(): void {
this.playerService.getPlayers().subscribe(
players => {
this.players = players;
},
error => this.errorMessage = <any>error
);
}
playerService
getPlayers(): Observable<IPlayer[]> {
return this.http.get<IPlayer[]>(`${this.url}/players`).pipe(
tap(data => console.log(JSON.stringify(data))),
catchError(this.handleError)
);
}
HTML组件
<div class="form-group">
<label for="player">Player</label>
<select id="player" #season class="custom-select" formControlName="playerid">
<option value="" disabled selected>Select Player (required)</option>
<option *ngFor='let player of players' value="{{player.playerid}}">{{player.player}}</option>
</select>
</div>
以下是屏幕截图,显示了带有我的调试输出的控制台:
所以我的问题是,我是否需要更改此代码以等到HTTP请求返回数据之后?还是我需要更改代码,以便在返回数据时做出反应?
答案 0 :(得分:1)
组件之间很难管理数据。如今,使用Angular,从 Presentation Component 中分离 Smart Component 是一个好习惯。
基本上,智能组件负责管理数据并将其传送到演示组件,其中演示组件仅负责显示数据。
这是关于主题的很好的解释。
示例:
呼叫组件(将成为我们的智能组件)
players = null;
constructor(private playerService: PlayerService) {}
ngOnInit() {
this.playerService.getPlayers().subscribe(players => this.players = players);
}
调用组件HTML
<app-players [players]="players"></app-players>
播放器组件(演示组件)
@Input() players;
播放器组件HTML
<div class="form-group">
<label for="player">Player</label>
<select id="player" #season class="custom-select" formControlName="playerid">
<option value="" disabled selected>Select Player (required)</option>
<option *ngFor='let player of players' value="{{player.playerid}}">{{player.player}}</option>
</select>
</div>
遵循这种做法(将数据从父组件倾泻到子组件)使工作变得更加轻松。
答案 1 :(得分:0)
为什么以这种方式编码,您应该仅在一个组件中拥有模型,并且如果希望子级的数据在父级使用事件发射器上可用,则子级可以在其自己的ngOnInit方法中执行该模型,以通知父级有关可用性的信息一旦服务返回响应,就会从子对象中提取玩家数组,然后通过eventemitter的通知重新初始化父组件的数组。
答案 2 :(得分:0)
您可以获取Observable
而不是访问实例变量。异步调用完成后,它将始终确保您拥有数据。
进行以下更改
getPlayers(): void {
return this.playerService.getPlayers(); //<-- return players Observable
}
ngOnInit() {
// Debugging code
console.log('Before this.playerComponent.getPlayers()');
// Nested component that gets the data from a service
this.playerComponent.getPlayers().subscribe(
players => this.players = players);
}
如果您还希望嵌套组件中的播放器,则可以使用相同的函数getPlayers()并进行订阅。
注意:由于代码是直接在stackoverflow编辑器中编写的,因此可能存在一些拼写错误或语法错误。请纠正自己。