【问题标题】:How to unsubscribe from observable without using ngOnDestroy or async pipe?如何在不使用 ngOnDestroy 或异步管道的情况下取消订阅 observable?
【发布时间】:2022-11-27 18:36:51
【问题描述】:

单击任何玩家名称时,主题都会更新,服务会返回一个 Observable,我将其显示在组件中。

在进行新订阅之前,我试图取消订阅组件中的可观察对象。有没有一种方法可以在不使用 ngOnDestroy / async 管道的情况下做到这一点?

ngOnInit() {
    this.playersubscription = this.playerService
      .getSelectedPlayer()
      .subscribe((player) => {
        this.selectedPlayer = player;
        // this.playersubscription.unsubscribe(); If I unsubscribe it here , the functionality breaks
      });
  }

服务:

 private selectedPlayer = new Subject<string>();

  getSelectedPlayer() {
    return this.selectedPlayer.asObservable();
  }

  updateSelectedPlayer(playerName: string) {
    this.selectedPlayer.next(playerName);
  }

这是我试过的Stackblitz。请帮助,在此先感谢!

【问题讨论】:

  • 如果您的实际服务是通过HttpClient 获取播放器,并且您在服务中返回了该可观察对象,它会在调用完成后自动取消订阅,因此您无需执行任何操作。
  • 在所选玩家之间切换时,我想退订。有办法吗?在我的情况下,组件永远不会死,所以我不能使用 ngOnDestroy()
  • 在您的情况下,您无需取消订阅(仅在 ngOnDestroy 中),ngOnInit 只会在创建组件时调用一次。并且 ngOnDestroy 仅在组件将被删除时使用。
  • 为什么组件永远不会被销毁?
  • 在您的情况下,应用程序组件是唯一显示的组件。如果您的代码位于子组件内(并且喜欢以路由器为例),那么如果您离开该组件,将调用 ngOnDestroy。

标签: angular typescript rxjs subject


【解决方案1】:

所以在这里我创建了一个子组件(名为 hello)。在孩子里面你会找到你的代码。应用程序组件有一个按钮,可以显示/隐藏孩子。所以你看到的 console.logsngOnInitngOnDestroy.

Here 是更新后的 Stackblitz 链接。

你好组件(子)

export class HelloComponent implements OnInit, OnDestroy {
  selectedPlayer: string;
  playersubscription: Subscription;

  constructor(private playerService: PlayerService) {}

  ngOnInit() {
    console.log('ngOnInit');
    this.playersubscription = this.playerService
      .getSelectedPlayer()
      .subscribe((player) => {
        this.selectedPlayer = player;
        // this.playersubscription.unsubscribe(); If I unsubscribe it here , the functionality breaks
      });
  }

  ngOnDestroy() {
    this.playersubscription.unsubscribe();
    console.log('ngOnDestroy');
  }

  players = [
    {
      name: 'Sachin',
      team: 'MI',
    },
    {
      name: 'Dhoni',
      team: 'CSK',
    },
    {
      name: 'Kohli',
      team: 'RCB',
    },
  ];

  selectPlayer(playerName) {
    this.playerService.updateSelectedPlayer(playerName);
  }
}

应用组件

export class AppComponent {
  showChild: boolean = true;

  constructor() {}
  onShowHideClick() {
    this.showChild = !this.showChild;
  }
}


..... and HTML part

<h1>APP COMPONENT</h1>
<button (click)="onShowHideClick()">SHOW / HIDE children</button>
<hr />
<hello *ngIf="showChild"></hello>

做你想做的,如果你理解所有你可以选择我的帖子作为答案。谢谢!

问候,弗洛里安

【讨论】:

    猜你喜欢
    • 2020-11-13
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2021-07-22
    相关资源
    最近更新 更多