Angular 共享服务订阅的角度行为
使用Angular,我有一个服务来共享来自不同组件的一些变量。 像这样:Angular 共享服务订阅的角度行为,angular,typescript,angular-ui-router,angular-lifecycle-hooks,Angular,Typescript,Angular Ui Router,Angular Lifecycle Hooks,使用Angular,我有一个服务来共享来自不同组件的一些变量。 像这样: import { Injectable } from "@angular/core"; import { BehaviorSubject } from "rxjs"; @Injectable() @Injectable({ providedIn: "root" }) /** * Service to manage all the global variables in order to use it in diff
import { Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";
@Injectable()
@Injectable({
providedIn: "root"
})
/**
* Service to manage all the global variables in order to use it in different components
*/
export class SharedService {
// Global variable of the path
private rPathSource = new BehaviorSubject(""); // Set up the source
currentRPath = this.rPathSource.asObservable(); // Make it Observable
constructor() {}
/**
* Function to change the global path from a component
* @param path string of the path of the R Folder for the result of the ML
*/
changeRPath(path: any) {
this.rPathSource.next(path);
}
}
然后我从一个组件订阅它。这样地:
组件1
constructor(private shared: SharedService) {}
ngOnInit() {
this.shared.currentRPath.subscribe(RPath => {
this.currentRPath = RPath;
// HERE I DO A GET REQUEST
});
}
从另一个组件,我改变变量如下:
组件2
this.shared.changeRPath("");
我有一个带有一些按钮的侧导航栏,每个按钮都会更改url和加载ng内容的组件
<ng-content></ng-content>
当我按下按钮在组件1上重定向时,我将引用变量,get请求完成。一切都很好
问题是,当我按下按钮在组件2上重定向时,共享变量会发生变化,因为我在组件1上使用了susbcribe,所以它会再次执行get请求。实际上,get请求位于subscribe的回调中
但奇怪的是组件1不再加载,因为它是组件2。组件更改时不应将其销毁?您不能忘记取消订阅,以避免这些悬而未决的订阅中出现内存泄漏 以下是两种方法:
takeUntil
:
export class MyComponent implements OnDestroy, OnInit {
private readonly destroyed = new Subject<void>();
constructor(private readonly shared: SharedService) {}
ngOnInit() {
this.shared.currentRPath.pipe(takeUntil(this.destroyed)).subscribe(/*...*/);
}
ngOnDestroy() {
this.destroyed.next(undefined);
this.destroyed.complete();
}
}
您在“root”中提供服务,使其成为一个单例。也就是说,你将在整个应用程序中共享状态。对于来自销毁组件的额外GET请求,您需要在订阅流之前插入
takeUntil(this.destromed)
操作符。如果我添加takeUntil(this.destromed),是否必须将根更改为singleton?takeUntil是npm模块吗?(这个:)@johndoetaketill是一个RxJS可管道操作符。看看这个,我问过这个问题,如果它是一个单一的实现,那么取消订阅就太过了。@rhavelka在OP的例子中,有一个源流发出的事件很可能是http请求流的switchMap
,这意味着每次都会调用它。注意你的退订并不是一种过分的行为,而是一种有意识的工程师的标志。
const mySubscription = this.shared.currentRPath.subscribe(/*...*/);
mySubscription.unsubscribe(); // when done.