当在Angular CLI中生成服务时,它会为Injectable装饰器添加一个'provided in'属性(默认值为'root')的额外元数据。

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

providedIn到底做什么?我假设这是使服务可用的像一个“全局”类型的单例服务的整个应用程序,然而,不会更干净地在AppModule的提供者数组中声明这样的服务?


当前回答

根据文档:

在@Injectable()元数据中注册提供者也是允许的 Angular通过从编译后的 应用程序,如果它没有使用。

其他回答

如果使用providedIn,可注入对象被注册为模块的提供者,而不需要将其添加到模块的提供者中。

从文档

服务本身是CLI生成的一个类 用@Injectable装饰。默认情况下,配置了这个装饰器 使用providedIn属性,该属性为服务创建提供者。 在这种情况下,providedIn: 'root'指定服务应该是 在根注入器中提供。

providedIn告诉Angular,根注入器负责创建你的服务的实例。以这种方式提供的服务将自动提供给整个应用程序,不需要在任何模块中列出。

服务类可以充当它们自己的提供者,这就是为什么在@Injectable装饰器中定义它们就是你所需要的全部注册。

简单. .

providedIn:'root'为整个应用程序创建了一个实例,而不需要从任何NgModule中提供它。只需通过@Injectable装饰器在服务中声明即可。

如果您希望为任何组件拥有该服务的一个新实例,那么可以通过组件的提供程序声明它。这将为该组件及其子组件(如果有的话)创建另一个新实例。因此,您可以有一个具有全局作用域的实例和一个组件的另一个实例。

根据文档:

在@Injectable()元数据中注册提供者也是允许的 Angular通过从编译后的 应用程序,如果它没有使用。

自Angular 6以来,providedIn: 'root'是最简单、最有效的提供服务的方法:

该服务将作为单例在整个应用范围内可用,不需要将其添加到模块的providers数组中(如Angular <= 5)。 如果服务只在一个惰性加载的模块中使用,那么该模块也会被惰性加载 如果它从未被使用过,它将不会包含在构建中(摇树)。

欲了解更多信息,请阅读文档和NgModule faq

Btw:

如果你不想要应用范围的单例,可以使用组件的提供者数组。 如果你想限制作用域,让其他开发人员无法在特定模块之外使用你的服务,可以使用NgModule的providers数组。