【问题标题】:Angular Material: mat-dialog opens multiple dialog boxes. Unsubscribe?Angular Material: mat-dialog 打开多个对话框。退订?
【发布时间】:2019-06-24 08:17:23
【问题描述】:

我正在使用here 提供的 NHL API 创建一个小型 Angular 应用程序。

我的想法是显示每支球队所有球员的列表,并且能够单击球员的姓名并弹出一个包含他的详细信息的对话框,并可以选择进入具有扩展详细信息和统计数据的另一个页面如果用户选择。

我正在使用角度材料垫对话框。

我的方法是在点击玩家姓名时,父组件将首先调用 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')
     }))
   })
}
}

所以数据传递并且弹出窗口工作,但是在关闭对话框并选择新播放器时,这一次,使用新播放器的数据(以及 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)
}

任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: angular angular-material


    【解决方案1】:

    您在正确的轨道上,问题在于订阅,所以这里有一个解决方案

    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')
         }))
       })

    通过使用take(1)(您也可以使用fist())运算符,您将在从已订阅的可观察对象中获取一个结果后自动取消订阅。

    【讨论】:

    • 谢谢!我对 rxjs 不太熟悉,所以我一直在寻找一个原生的角度解决方案,没想到这一点。完美运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    相关资源
    最近更新 更多