Angular 角度8:提取到其他服务时,主体部分不工作

Angular 角度8:提取到其他服务时,主体部分不工作,angular,angular8,behaviorsubject,Angular,Angular8,Behaviorsubject,我遇到了一个非常奇怪的问题:在我的应用程序中,我遵循了让状态服务处理所有状态的原则。随着应用程序的发展,我决定创建亚州服务。我将所有相关函数提取到一个专用服务中。除其他外,此部分已从state.service.ts移至bubble03-state.service.ts: 在另一个服务中 订阅 如果组件多次调用该方法,则会记录以下输出 > updating with value Kontoführung > newly visible Kontoführung updating &g

我遇到了一个非常奇怪的问题:在我的应用程序中,我遵循了让状态服务处理所有状态的原则。随着应用程序的发展,我决定创建亚州服务。我将所有相关函数提取到一个专用服务中。除其他外,此部分已从state.service.ts移至bubble03-state.service.ts:

在另一个服务中

订阅

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

> 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
一旦我将方法及其相应的行为主题放回到主服务中,一切都按预期进行。什么可能导致这种行为?除了名称之外,国家服务之间没有区别。两者都以root格式提供

编辑:

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

StateService位于CoreModule中,并在root中提供。CoreModule仅在AppModule中导入。 Bubble03StateService位于延迟加载的模块中,也在root中提供。 Bubble03StateService用于延迟加载的模块和第三个服务,该服务也位于CoreModule中,并在root中提供,而StateService用于每个模块。 根据Richard Dunn的建议,我重新定位了Bubble03StateService并尝试了一些事情。它现在也位于CoreModule中

当我删除provideIn:'root'并将这两个服务都放在AppModule的providers数组中时,常规的StateService仍然可以正常工作,但Bubble03StateService抛出了一个NullInjectorError:no providers for。。。 重新插入provideIn:“root”并从AppModule中删除,服务被加载,但发生了一些我不理解的事情:在服务的构造函数中,我创建了一个随机数,并在调用服务的函数时记录它。将BehaviorSubject及其相应的更新方法放入StateService中时,无论是谁调用该方法第三个服务和延迟加载的组件,随机数始终相同。但是当我把它放回Bubble03StateService中时,除了它的名称之外,它在所有方面都与StateService相同,当从第三个服务和延迟加载的组件调用时,随机数是不同的。这让我更加困惑,因为现在CoreModule的三个服务都应该是单例的。如果不是,为什么StateService和Bubble03StateService以相同的方式声明、提供和定位时不是singleton和Bubble03StateService?
可能是Angular 8的模块延迟加载导致了这个问题。具体来说,如果您使用依赖项注入的@Injectable{providedIn:'root'}方法,它可能正在创建单例服务,具体取决于订阅服务器父模块与根模块的关系


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

我终于找到了问题的原因

不知何故,当自动将服务导入到另一个服务中时,自动导入函数将extension.js添加到import语句中。这真的很难理解,因为你通常不会明确地检查它

虽然在这个位置甚至没有一个.js文件,Angular理解这一点,并从.ts文件中导入正确的类/服务/组件等。但它创建了一个新的服务实例,消除了单例原则


因此,最后,从导入中删除.js扩展名是必须完成的全部工作。

我无法发现问题,您是否有任何错误?您是否验证了该图表。选项。数据[0]。实际上正在调用click?只需注意:间距使您的代码更容易阅读。此外,行为主体通过调用其.value方法公开其当前值。@RichardDunn是的,该方法实际上已被调用,否则该服务的日志将不可见,而且它位于图表对象的上下文中,该对象在单击时也会被操作。没有错误,只是从服务调用的下一个方法似乎没有触发订阅。感谢您对共享空间的反馈,我想您指的是服务中的集群主题、方法和if语句?我明白了,我误解了日志。“其他”服务如何导入“数据”服务?换句话说,依赖注入是如何管理的。您的重构可能导致组件和“其他”服务具有两个不同的数据服务实例,因此数据服务正在记录新事件,但您的其他服务订阅了另一个未获取事件的实例。我不认为这是个问题,但这是可能的。我最后一次通信
nt可能比我想象的更可能,在默认启用Angular 8的延迟加载配置的情况下,它可能使用依赖注入的providedIn:“root”方法为您创建单例服务。您应该通过在根模块中使用:@NgModule{providers:[Bubble03StateService]}将此更改为另一个方法。这将保证它是一个单例服务。我认为这应该是问题所在。我没有说明定义了第二个子状态服务的模块确实是延迟加载的。稍后我会尝试并给你反馈,请随时写信和回答,以便我可以将其标记为已解决!在尝试了你的建议之后,我更新了我的问题,不幸的是,我仍然有一个问题。我已经思考了一点,但想不出有什么可能是错的。我经常使用RxJS,包括Angular、Node和React,我以前从未见过这个问题,所以我认为它一定是Angular的DI。可能不是服务被延迟加载,而是组件导致了问题?是的,具有onClickRowElement方法的组件被延迟加载,但不是现在包含所有三个服务的CoreModule。我想我找到了原因,但没有解释。看起来——虽然是在根目录中提供的——如果这个服务被注入到另一个服务中,它就不再是一个单一的服务了。检查我的答案,最终,原因是非常琐碎的——噩梦的东西。抢手货
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