Dan*_*bot 1 angular-material angular
我正在使用此处提供的 NHL API 创建一个小型角度应用程序。
我的想法是显示每支球队的所有球员的列表,并且能够单击球员的姓名并弹出一个包含其详细信息的对话框,如果用户选择。
我正在使用有角度的材料垫对话框。
我的方法是点击玩家的名字后,父组件将首先调用 API 来检索该玩家的数据,一旦解决,将该数据传递给对话框组件。
export class PlayersListComponent implements OnInit {
team: string;
teamId: number;
teamPlayers = [];
selectedPlayer;
constructor(private playersService: PlayersService, private route:
ActivatedRoute, private router: Router, public dialog: MatDialog) { }
//additional code
getPlayerDetails(player){
let playerId = +player.person.id
this.playersService.getPlayerDetails(playerId)
this.playersService.selectedPlayerUpdated.subscribe((data)=>{
this.selectedPlayer = data;
let dialogRef = this.dialog.open(PlayerPopupComponent, {
data: this.selectedPlayer
});
dialogRef.afterClosed().subscribe((result=>{
console.log('dialog was closed')
}))
})
}
}
Run Code Online (Sandbox Code Playgroud)
因此数据已传递并且弹出窗口起作用,但是在关闭对话框并选择新玩家后,这一次将使用新玩家的数据(以及 2 个控制台日志)创建 2 个重复的弹出窗口。对于第三个玩家,创建 3 个弹出窗口,依此类推。
我有一种感觉,我要么需要在某个地方取消订阅(不确定在哪里,因为进行订阅的父组件永远不会被销毁,只有弹出组件被销毁,但没有可观察到的,因为 API 调用是从父组件进行的) 。
或者我的对话框函数放置在错误的位置?
这是入口组件:
export class PlayerPopupComponent implements OnInit, OnDestroy {
public thisPlayer;
constructor(public dialogRef: MatDialogRef<PlayersListComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) { }
ngOnInit() {
this.thisPlayer = this.data
console.log(this.thisPlayer)
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激,谢谢。
你是在正确的轨道上,问题出在订阅上,所以这里有一个解决方案
this.playersService
.selectedPlayerUpdated
.pipe(take(1))
.subscribe((data)=>{
this.selectedPlayer = data;
let dialogRef = this.dialog.open(PlayerPopupComponent, {
data: this.selectedPlayer
});
dialogRef
.afterClosed()
.pipe(take(1))
.subscribe((result=>{
console.log('dialog was closed')
}))
})
Run Code Online (Sandbox Code Playgroud)
通过使用take(1)
(您也可以使用fist()
)运算符,您将在从订阅的可观察对象中获取恰好一个结果后自动取消订阅。