【问题标题】:What would cause an Angular2 service to create multiple instances?什么会导致 Angular2 服务创建多个实例?
【发布时间】:2019-02-27 18:20:59
【问题描述】:

我创建了一个服务,并在我的项目中以“根”提供它(使用标准快捷方式)。但是,它似乎是创建多个实例而不是使用同一个实例。我通过在构造函数中设置一个等于随机值的实例变量 ID 来诊断这一点,然后在方法调用上将其打印到控制台。

@Injectable({
    providedIn: 'root'
  })

console.log(`Hodor ${this.ID}`);

这是一个问题,因为附加实例似乎无法访问我指定用于输出的组件。当我通过组件触发事件时,服务会处理它们并将输出放置在该组件中。但是,当我通过另一个组件触发它们时,它们会转到第二个实例并且不会产生输出。

我的应用有多个功能模块,先导入一个核心模块,然后再导入应用模块(app-->core-->feature)。我尝试在单独的模块中提供服务并将其导入应用程序,但这没有任何区别。有什么办法可以防止第二个实例出现吗? 'root' 不应该解决这个问题吗?

此时,我正在考虑使用经典的 OOP 策略,即为服务设置一个静态变量,然后让构造函数设置它,或者如果它已经定义,则返回它。然而,这种模式绝对不是标准的 Angular。

【问题讨论】:

  • 您是否在 providers 数组中的某个位置添加了此服务,这可以解释几个实例。
  • 我对提供者的所有 .ts 文件进行了 grep 搜索,但没有找到任何引用,所以看起来我完全使用了 providedIn: 语法。经过一些额外的测试后,我觉得应该归咎于我的功能模块导入策略。我正在尝试让 FM-A 模块将更新推送到另一个 FM-B 中的组件。我尝试将 FM-B 导入 FM-A 并尝试将 FM-A 和 FM-B 导入 app.module 但它似乎没有任何改变。不知何故,第二个功能模块似乎正在创建自己的实例。

标签: angular


【解决方案1】:

好的,我有答案,这是一个很好的答案。 VSCode 有一个错误,导致它间歇性地将 .js 扩展名添加到 Typescript 类导入。这通常不会影响代码的功能,因为 .js 类确实是由 TS 转译器在运行时创建的(尽管我们都希望它指向原始的 .ts 文件)。但是,这会导致 Angular 将 .js 文件识别为不同的文件,如果该文件包含服务,则会导致它创建一个新的服务实例,就像这里发生的那样。这是我将来一定会关注的。

【讨论】:

  • 对我来说类似的问题。我的服务的 import 语句有时带有 .js 扩展名,有时没有。具有使 Angular 查看两个不同文件的相同效果。此外,我们正在使用可能与它有关的 ngUpgrade。
【解决方案2】:

这很可能是由一个不同的模块声明了自己的服务提供者引起的 - 通过在其 providers 中列出它,或者通过导入一个提供服务的模块。

您可以通过在服务构造函数中设置断点并检查调用者的变量以找出哪个注入器创建了第二个实例(以及哪个令牌,如果相关的话)来调试它。这应该会引导您进入声明附加提供程序的模块。

【讨论】:

  • 我尝试重命名服务(文件名和类名)并通过每次调用来更新它。这并没有解决它。我会尝试一个断点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-12-11
  • 1970-01-01
相关资源
最近更新 更多