有没有办法避免在除了取消订阅ngOnDestroy中的组件之外的组件中的behaviorSubject上进行重复订阅?到目前为止,这是我发现避免重复订阅的唯一方法,当我在一个可观察的创建订阅的组件上来回导航时。
示例:
用户服务
@Injectable()
export class UserService {
constructor(private http: Http) {
this.setCurrentUser();
}
private currentUser$ = new BehaviorSubject<User>(null);
public getCurrentUser(): Observable<User> {
return this.currentUser$.asObservable();
}
public setCurrentUser(): void {
this.getLoggedUser(); //
}
private getLoggedUser(): void {
let getCurrentUserUrl = 'http://127.0.0.1:8000/users/current/'
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({
headers: headers
});
options.withCredentials = true;
this.http.get(getCurrentUserUrl, options)
.map(this.toUser)
.catch(this.handleError)
.subscribe(
user => this.currentUser$.next(user),
error => console.log("Error subscribing to currentUser: " + error)
);
}
private toUser(res: Response): User {
let body = res.json();
return body || { };
}
}
从用户服务订阅observable的组件......
export class AppComponent implements OnInit, OnDestroy {
currentUserSubscription:any;
constructor(
private userService:UserService,
private authentificationService:AuthenticationService
) {}
user:User;
ngOnInit() {
this.currentUserSubscription = this.userService.getCurrentUser().subscribe(
data => {
this.user = data;
console.log('Main : ', this.user);
}
);
}
ngOnDestroy() {
// I want to avoid writing this for every subscription
this.currentUserSubscription.unsubscribe();
}
}
如果我将多个时间导航到组件,它会被多次创建和销毁。每次使用组件初始化时都会创建订阅,并且必须使用组件销毁订阅。如果没有,它将在下一个组件初始化时重复...
有没有办法避免在ngOnDestroy中清理订阅?
答案 0 :(得分:3)
如果您只想在模板上使用异步管道一次订阅,异步管道将自动管理取消订阅。如果您喜欢这种方法,则需要使用智能组件和表示组件组合您的应用程序。请检查此answer
另一种取消订阅的方法是创建主题,以便订阅完成,直到主题发出一个值。你应该总是取消订阅,否则你会有内存泄漏。
export class AppComponent implements OnInit, OnDestroy {
currentUserSubscription:any;
constructor(
private userService:UserService,
private authentificationService:AuthenticationService,
private _destroy : Subject() = new Subject();
) {}
user:User;
ngOnInit() {
this.currentUserSubscription = this.userService.getCurrentUser()
.takeUntil(this._destroy)
.subscribe(
data => {
this.user = data;
console.log('Main : ', this.user);
}
);
}
ngOnDestroy() {
this._destroy.next();
this._destroy.unsubscribe();
}
}
答案 1 :(得分:0)
对于Angular 8,这解决了我的问题,即我从许多组件中进行订阅,并且只希望从一个组件中删除一个订阅者的观察者。 这种模式将防止订阅重复,并保存其他处于活动状态的组件中的订阅。
在组件中将订阅声明为对象:
sub: Subscription;
constructor(private userService: UserService) {
}
ngOnInit() {
this.sub = this.userService.user.subscribe(user => this.subscription(user));
}
subscription(user) {
// do whatever you want during notification
}
ngOnDestroy() {
this.sub.unsubscribe();
}