架构:
(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。
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(); }
宣告一个 Subscriptionsubscription = 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(); }
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 结束后便会取消订阅