Angular 8:提取到另一个服务时,BehaviorSubject 部分不起作用

Angular8: BehaviourSubject partially not working when extracting to another Service

我遇到了一个非常奇怪的问题:在我的应用程序中,我遵循了让状态服务处理所有状态的原则。随着应用程序的增长,我决定创建子状态服务。我将所有相关功能提取到专用服务中。其中,这部分从 state.service.ts 移动到 bubble03-state.service.ts:

@Injectable({
  providedIn: 'root'
})
export class Bubble03StateService {

  constructor() { }

  /* tslint:disable:rule1 member-ordering */ 

  // ...

  public currentVisibleEFSubcontainer$ = new BehaviorSubject<string>('');
  private currentSubjectValue = '';
  updateCurrentVisibleEFSubcontainer(newVisibleContainer: string): void {
    console.log(`updating with value ${newVisibleContainer}`);
    if (newVisibleContainer !== this.currentSubjectValue) {
      this.currentVisibleEFSubcontainer$.next(newVisibleContainer);
      this.currentSubjectValue = newVisibleContainer;
    } else {
      this.currentVisibleEFSubcontainer$.next('');
      this.currentSubjectValue = '';
    }
  }

}

从两个位置调用方法 updateCurrentVisibleEFSubcontainer(),一个是组件,一个是另一个服务。现在奇怪的是:一旦我将此代码移动到新的子状态服务,只有一个调用触发订阅,而另一个调用则不会。我真的无法解释为什么,因为它的代码完全相同,只是在另一个地方。所有其他移动的功能都可以正常工作。在这两个电话之后:

在组件中

onClickRowElement(): void {
  if (this.rowElementAmount > 0) {
    this.bubble03State.updateCurrentVisibleEFSubcontainer(this.rowElementTitle);
    this.rowElementClicked.emit(this.rowElementTitle);
  }
}

在另一个服务中

chart.options.data[0].click = (e) => {
  this.explodePie(e);
  this.bubble03State.updateCurrentVisibleEFSubcontainer(e.dataPoint.name);
};

订阅

this.bubble03State.currentVisibleEFSubcontainer$.subscribe(
  newVisibleEFContainer => {
    this.handleExpandableSubContainer(newVisibleEFContainer);
    console.log(`newly visible ${newVisibleEFContainer}`);
  }
);

如果从组件中多次调用该方法,则会记录以下输出

> updating with value Kontoführung 
> newly visible Kontoführung updating
> with value Versand & Bearbeitung 
> newly visible Versand & Bearbeitung
> updating with value Versand & Bearbeitung 
> newly visible

但是,从服务调用方法会产生以下日志

> updating with value Kontoführung
> updating with value Versand & Bearbeitung
> updating with value Buchungsgebühren

只要我将方法及其相应的 BehaviourSubject 放回主服务中,一切都会按预期进行。什么可能导致这种行为?状态服务之间没有区别,除了名称。两者都在 root 中提供。

编辑:

为了澄清,发布问题时的初始情况如下:

按照 Richard Dunn 的建议,我重新定位了 Bubble03StateService 并尝试了一些东西。它现在也位于 CoreModule

可能是 Angular 8 的延迟加载模块导致了这个问题。具体来说,如果您使用 @Injectable({ providedIn: 'root' }) 依赖注入方法,它可能会创建单例服务,具体取决于订阅者父模块与根模块的关系。

您应该删除此方法并改用:@NgModule({ providers: [Bubble03StateService] }) 在您的根模块中。这将保证它是一个单例服务。

我终于找到问题的原因了。

不知何故,在其他服务中自动导入该服务时,自动导入功能将扩展名 .js 添加到导入语句中。这真的很难捕捉到,因为您通常不会明确检查它。

虽然此位置甚至没有 .js 文件,但 Angular 以某种方式理解这一点并从 [=12= 导入正确的 class / 服务 / 组件等]-文件。但是它创建了一个新的服务实例,破坏了单例的原则。

所以最后,只需从导入中删除 .js 扩展即可。