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

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

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


当前回答

简单. .

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

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

其他回答

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

从文档

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

从文档

什么是可注入装饰器?

将一个类标记为可用于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 {
}

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

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

简单. .

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

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

根据文档:

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