【问题标题】:Is Singleton Instance of a service provided to child components?服务的单例实例是否提供给子组件?
【发布时间】:2020-11-20 04:20:24
【问题描述】:

假设有一个父组件 P 。有两个子组件 B 和 C 。 我在 P 的 ElementInjector 中提供了一个服务(假设是 MyService),并在 P 组件类的构造函数中注入了该服务。 我在两个子组件 B 和 C 中再次注入服务。

我的问题是,在这种情况下,B、C 和 P 可用的服务实例是否相同?

如果我只在两个子组件 B 和 C 中注入服务,而不是在父组件 P 中注入服务会怎样。在这种情况下,B 和 C 会有单独的 MyService 服务实例吗?

这是帮助可视化组件的图像。

编辑:

服务等级:

@Injectable()
export class MyService(){
   constructor(){
console.log('My Service instantiated');
}
}

P 组件的类:

import {MyService} from '...';

@Component({

selector:'Pcomp',
...
providers:[MyService]
})

export class PComponent {
 constructor(public myservice:MyService){
}
}

组件B类:

import {MyService} from '...';

@Component({

selector:'Bcomp',
...

})

export class BComponent {
 constructor(public myservice:MyService){
}
}

组件C类:

import {MyService} from '...';

@Component({

selector:'Ccomp',
...
})

export class CComponent {
  constructor(public myservice:MyService){
}
}

【问题讨论】:

  • 要获得更详细的答案,您能否分享一下您是如何指定服务的(例如,@Injectable 装饰器的外观如何)以及您如何在应用程序的其他部分传递/注入它?
  • 服务是在组件级别提供的,具体是在P的组件类的@Component装饰器上。 @Component({selector:'P',template:'...',providers:[MyService]})...
  • 只需在您的第一篇文章中分享代码粗略代码,也包括服务,这样我们就可以看到您将哪些选项传递给Injectable 装饰器:)
  • 服务被/被用作跨模块的单例。从 Angular 9 开始,服务现在不仅仅是单例了。同样,这完全取决于您对元数据的使用,特别是 providedInproviders。看看这里,您还可以使用组件 angular.io/guide/… 限制您的提供者范围。由于提供者处于 P 组件级别,因此在您的情况下 B 和 C 应该具有相同的实例。
  • @bron1010 是的,我也这么认为。所有三个 P 、 B 和 C 将共享同一个 MyService 服务实例。

标签: angular dependency-injection angular-services angular2-providers


【解决方案1】:

如果您使用的是 Angular CLI,则会使用类似的方式生成服务

@Injectable({
  providedIn: 'root',
})  

所以服务是作为单例生成的,这意味着应用程序中只能存在一个实例。我认为建议将服务创建为单例。

【讨论】:

  • 服务是否应该是单例的,最佳实践最终归结为您想要实现的目标。有时您想要全局单例,有时您想要由功能模块限定的单例(但为每个嵌入模块新实例化),.. - 同样,取决于您想要实现的目标。
  • 感谢您的澄清!!!我从未使用过功能模块范围内的服务。
  • 不客气。欲了解更多信息:angular.io/guide/singleton-services
【解决方案2】:

服务被/被用作跨模块的单例。 从 Angular 9 开始,服务现在不仅仅是单例了。我的意思是 拥有带有延迟加载模块的新服务实例。

延迟加载是指仅在需要时才加载模块;为了 例如,当路由时。它们不会像热切地那样立即加载 加载的模块。这意味着在其提供商中列出的任何服务 数组不可用,因为根注入器不知道 这些模块。 -- angular.io 指南

因此,这完全取决于您对元数据的使用,尤其是使用 providedIn 用于服务注入装饰器,providers 用于组件装饰器。

在上述情况下,如果我们将MyService 限制为组件的提供者,它将被限制为 零件。提到上面的一段代码如下。

@Component({
    selector:'Pcomp',
...
    providers:[MyService]
})

由于提供者处于Pcomp 级别,Pcomp 及其后代BcompCcomp 可以利用MyService 作为单例。

参考:https://angular.io/guide/providers#limiting-provider-scope-with-components

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    相关资源
    最近更新 更多