iT邦幫忙

0

[Angular][RxJs][誤區筆記] Observable Unsubscribe

架構:
(1) userComponent:
訂閱(subscribe)sharedService 的 User資料

(2)sharedService
利用Subject接收其他componenttj傳來的User資料。

問題:
userComponent 放在一個dialog裡面,預期每次開啟dialog,
都會從sharedService取當下選取到的User,後續接著打一些api。

  constructor(private service: SharedService) { }

  ngOnInit() {
    this.service.getCurrentUser().subscribe(
      user => console.log(user)
    );
  }

但在每一次重新開啟dialog時,會連曾選取過的user一起帶出來 。

如:
第一次點選 : Peter >> Peter
第二次點選 : Winston >> Peter , Winston
第三次點選 : Rossi >> Rossi , Peter , Winston

造成後續打api重複觸發。

解決

因為 subscibe 並不會因為 dialog 關閉就取消訂閱,以至於每次開啟dialog都會發起一個新的訂閱,
需要手動unsubscirbe 或使用 async pipe。

  1. 利用 Subscription Unsubscirbe

  subscription = new Subscription();

  constructor(private service: SharedService) { }

  ngOnInit() {
    this.subscription.add(
      this.service.getCurrentUser()
        .pipe(
          // my api.......
        ).subscribe(result => console.log(result))
    );
  }

  ngOnDestroy(): void {
    console.log('ngOnDestroy');
    this.subscription.unsubscribe();
  }

宣告一個 Subscription
subscription = new Subscription();

將Subscribe 加到 Subscription 中

    this.subscription.add(
      this.service.getCurrentUser()
        .pipe(
          switchMap((user: User) => this.service.getDivision(user.ID))
        ).subscribe(division => this.division = division)
    );

在 Dialog 關閉 ngOnDestroy 取消訂閱

  ngOnDestroy(): void {
    console.log('ngOnDestroy');
    this.subscription.unsubscribe();
  }
  1. Async Pipe
    會自動取消取消訂閱
  email$: Observable<string>;

  constructor(private service: SharedService) { }

  ngOnInit(): void {
    this.email$ = this.service.getCurrentUser()
      .pipe(
        switchMap((user: User) => this.service.getEmail(user.ID))
        );
  }

宣告回傳的Observable<string>

email$: Observable<string>;

html 使用 async pipe

  <ng-container *ngIf="email$ | async as email">
    <li class="list-group-item">{{email}}</li>
  </ng-container>

async pipe 在component 結束後便會取消訂閱


尚未有邦友留言

立即登入留言