我试图了解调用角度服务时使用ngDestroy或退订的最佳实践。通过下面的示例,有人可以告诉我在这种情况下如何正确使用ngDestroy吗?
this.submitPostService.getUserName(this.userId).subscribe(user => {
console.log("THIS IS THE USER!");
console.log(user);
this.username = user.posts.name;
console.log(this.username);
});
角度服务
getUserName(id: string) {
return this.http.get<{ posts: any }>(
`http://localhost:3000/api/user/${id}?username=` + id
);
}
答案 0 :(得分:1)
看下面的例子。这样,我可以确保在销毁组件时总是发生取消订阅的情况。
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
//...
export class AppComponent implements OnInit, OnDestroy {
private destroyed$ = new Subject();
//...
ngOnInit() {
this.submitPostService.getUserName(this.userId)
.pipe(takeUntil(this.destroyed$))
.subscribe(user => {
console.log(user);
});
}
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
}
此处的关键元素是destroyed$
和takeUntil
一个rxjs运算符。在您的服务电话中,您可以使用.pipe(takeUntil(this.destroyed$)
来简单地说,订阅直到destroyed $为真。您可以在所有组件订阅中使用它。
希望此帮助(: 您可以查看this article了解更多信息。
答案 1 :(得分:0)
您必须首先将可观察对象保存在类级变量中
this.subscription = this.submitListingService.getUserName(this.userId).subscribe(...
然后在组件销毁方法或其他方法中,可以将方法取消订阅
this.subscription.unsuscribe();
答案 2 :(得分:0)
以您的示例为例,http.get是一个自我完成的方法,这意味着您不需要按组件本身退订。 您可以查看类似的问题:Is it necessary to unsubscribe from observables created by Http methods?
我想以下模板足以满足仅视图逻辑组件的需求:
export class AppComponent implements OnInit, OnDestroy {
renderTimeSubs: Subscription[] = [];
keepUpdateSub1: Subscription = null;
constructor(private aService: AService) {}
ngOnInit() {
this.renderTimeSubs = [];
this.aService.selfClosedObs.subscribe();// you don't need to handle the self-completed subscription
const sub1 = this.aService.nonSelfClosedObs().subscribe();
this.renderTimeSubs.push(sub1);
}
updateSubscription() { /** handle in service is a better manner */
if (this.keepUpdateSub1 && !this.keepUpdateSub1.closed) {
this.keepUpdateSub1.unsubscribe();/** close Observable between Init&Destroy component*/
}
this.keepUpdateSub1 = aService.getANewNonClosedObservable;/** new non-closed Observable*/
}
ngOnDestroy() {
this.renderTimeSubs .forEach(x => x.unsubscribe());
if (this.keepUpdateSub1 && !this.keepUpdateSub1.closed) {
this.keepUpdateSub1.unsubscribe();
}
}
}