使用Angular 6,下面是创建单件服务的首选方法:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class UserService {
}
来自Angular doc: 当您在根级别提供服务时,Angular会创建一个HeroService的单个共享实例,并注入任何要求它的类。在@Injectable元数据中注册提供程序还允许Angular通过删除服务来优化应用程序(如果事实证明它不会被使用)。
此外,
providers: [
// no need to place any providers due to the `providedIn` flag...
]
那么,这是否意味着我们不再需要CoreModule?我们可以将服务和其他常用模块直接导入AppModule。
答案 0 :(得分:1)
如果CoreModule仅包含服务,那将是正确的。但是,它确实包括其他内容,例如一次性组件。
来自Angular Docs:
请在CoreModule中收集应用程序范围内的一次性组件。在应用启动时将其导入一次(在AppModule中),再也不要将其导入其他任何地方。 (例如NavComponent和SpinnerComponent)。
答案 1 :(得分:1)
那拦截器和守卫呢?我猜这件事可能是全球性的。我同意您对CoreModule的考虑,因为它没有声明,而只有纯服务,但是我认为Guards和Interceptor也应该考虑周到。
答案 2 :(得分:1)
我仍然保留CoreModule用于一次性组件和Http拦截器,现在推荐使用providedIn
属性来注册单例服务,为清楚起见,我将所有我的单例服务放在core / services目录下< / p>
答案 3 :(得分:0)
文档中明确指出,我认为它是创建CoreModule的替代方法:
在Angular中有两种使服务成为单例的方法: 声明根为@Injectable()提供的属性的值
将服务包含在AppModule或仅由AppModule导入的模块中
如果您的应用程序具有纯服务的CoreModule,则可以简单地摆脱它(如果您当然认为不必要),尽管我不建议这样做,但对我来说,我认为拥有一个CoreModule,因为我可以在项目中轻松找到它,并告诉我哪些服务是应用程序的基础,我们只需要一个实例,而不必在IDE中打开搜索对话框并查找具有{已设置{1}}。
答案 4 :(得分:0)
当Angular引擎开始初始化组件,并且您已经在构造函数中声明了服务时,angular尝试将声明的服务的实例传递给组件。因此,角度应该以某种方式知道可以将实例带到哪里,在某些情况下providers数组会出现。
当您声明所需的服务时没有提供对:核心对,我们将创建该服务的非单例实例。这意味着,当angular破坏组件时,组件中声明的服务也将被破坏。
如前所述,有两种方法可以声明应用程序级别的单例服务:1.将它们声明到相关模块的提供程序中; 2.将它们声明为具有providerIn:核心对的组件的提供程序。
关于@Injectable装饰器的有趣注释。仅当服务注入另一个服务时才需要。例如,如果在服务中注入http服务,则必须添加@Injecrable装饰器。
这就是依赖项注入的工作方式。
答案 5 :(得分:0)
我认为创建核心模块已经过时了,因为服务可以定义自己通过providedIn: root
注册到根目录。
(老!)角度样式指南建议在v6之前创建核心模块:https://v6.angular.io/guide/styleguide
但是从v7开始,不再建议创建一个核心模块。
我认为正是因为这个原因(providedIn: root
完成了任务)。
答案 6 :(得分:0)
provideIn: root
在有多个应用程序项目的情况下可能很有用。在这种情况下,您将拥有一个有多个项目的棱角型工作空间。
而且,您永远都不希望您的项目对工作区的core module
有某种依赖性,因为它不允许您独立运行项目。
在这种情况下,您将服务保留在库中,并使用providedIn: 'root'
使它们成为单例。
答案 7 :(得分:0)
providedIn: 'root'
是声明方式core module
是命令式方式如果您需要有条件地注入提供者,在一个模块中很容易做到,而 core module
是为您的应用导入所有必需服务的那个。例如,这对于根据环境变量导入测试或生产服务很有用。
如果您的服务只有一个版本,那么 providedIn: 'root'
是一个不错的选择。