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

使用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 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.