当在Angular CLI中生成服务时,它会为Injectable装饰器添加一个'provided in'属性(默认值为'root')的额外元数据。
@Injectable({
providedIn: 'root',
})
providedIn到底做什么?我假设这是使服务可用的像一个“全局”类型的单例服务的整个应用程序,然而,不会更干净地在AppModule的提供者数组中声明这样的服务?
当在Angular CLI中生成服务时,它会为Injectable装饰器添加一个'provided in'属性(默认值为'root')的额外元数据。
@Injectable({
providedIn: 'root',
})
providedIn到底做什么?我假设这是使服务可用的像一个“全局”类型的单例服务的整个应用程序,然而,不会更干净地在AppModule的提供者数组中声明这样的服务?
当前回答
简单. .
providedIn:'root'为整个应用程序创建了一个实例,而不需要从任何NgModule中提供它。只需通过@Injectable装饰器在服务中声明即可。
如果您希望为任何组件拥有该服务的一个新实例,那么可以通过组件的提供程序声明它。这将为该组件及其子组件(如果有的话)创建另一个新实例。因此,您可以有一个具有全局作用域的实例和一个组件的另一个实例。
其他回答
如果使用providedIn,可注入对象被注册为模块的提供者,而不需要将其添加到模块的提供者中。
从文档
服务本身是CLI生成的一个类 用@Injectable装饰。默认情况下,配置了这个装饰器 使用providedIn属性,该属性为服务创建提供者。 在这种情况下,providedIn: 'root'指定服务应该是 在根注入器中提供。
自Angular 6以来,providedIn: 'root'是最简单、最有效的提供服务的方法:
该服务将作为单例在整个应用范围内可用,不需要将其添加到模块的providers数组中(如Angular <= 5)。 如果服务只在一个惰性加载的模块中使用,那么该模块也会被惰性加载 如果它从未被使用过,它将不会包含在构建中(摇树)。
欲了解更多信息,请阅读文档和NgModule faq
Btw:
如果你不想要应用范围的单例,可以使用组件的提供者数组。 如果你想限制作用域,让其他开发人员无法在特定模块之外使用你的服务,可以使用NgModule的providers数组。
从文档
什么是可注入装饰器?
将一个类标记为可用于Injector创建。
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class UserService {
}
服务本身是CLI生成的一个类,并使用@Injectable()进行装饰。
providedIn到底做什么?
通过将可注入对象与@NgModule或其他InjectorType关联,或者指定该可注入对象应该在“根”注入器中提供,这将是大多数应用程序中的应用级注入器。
providedIn: Type<any> | 'root' | null
提供:“根”
当你在根级提供服务时,Angular会创建一个单独的、共享的服务实例,并将它注入到任何需要它的类中。在@Injectable()元数据中注册提供商还可以让Angular通过在编译后的应用中删除不使用的服务来优化应用。
提供:模块
也可以在特定的@NgModule中指定一个服务。例如,如果您不希望某个服务对应用程序可用,除非它们导入您创建的模块,您可以指定该服务应该在模块中提供
import { Injectable } from '@angular/core';
import { UserModule } from './user.module';
@Injectable({
providedIn: UserModule,
})
export class UserService {
}
这种方法是首选的,因为如果没有注入服务,它可以对服务进行摇树(摇树是构建过程中的一个步骤,从代码库中删除未使用的代码)。
如果不能在服务中指定应该由哪个模块提供该服务,你也可以在模块中声明该服务的提供者:
import { NgModule } from '@angular/core';
import { UserService } from './user.service';
@NgModule({
providers: [UserService],
})
export class UserModule {
}
根据文档:
在@Injectable()元数据中注册提供者也是允许的 Angular通过从编译后的 应用程序,如果它没有使用。
简单. .
providedIn:'root'为整个应用程序创建了一个实例,而不需要从任何NgModule中提供它。只需通过@Injectable装饰器在服务中声明即可。
如果您希望为任何组件拥有该服务的一个新实例,那么可以通过组件的提供程序声明它。这将为该组件及其子组件(如果有的话)创建另一个新实例。因此,您可以有一个具有全局作用域的实例和一个组件的另一个实例。