在Angular CLI中生成服务时,它会添加带有'provided in'属性的额外元数据,默认值为'root',用于Injectable装饰器。
@Injectable({
providedIn: 'root',
})
究竟提供了什么?我假设这使得服务可用作整个应用程序的“全局”类型单例服务,但是,在AppModule的提供者数组中声明此类服务会不会更清晰?
更新
对于其他任何人,以下段落也提供了另一个很好的解释,特别是如果您想要仅为功能模块提供服务。
现在有一种新的,推荐的方式直接注册提供商 在
@Injectable()
装饰器中,使用新的providedIn
属性。它接受'root'
作为您的价值或任何模块 应用。当您使用'root'
时,您的injectable
将成为。{1}} 在应用程序中注册为单例,您不需要 将其添加到根模块的提供程序。同样,如果你使用providedIn: UsersModule
,injectable
注册为UsersModule
的提供商,但未将其添加到providers
模块。“ - https://blog.ninja-squad.com/2018/05/04/what-is-new-angular-6/
更新2:
经过进一步调查后,我认为只有providedIn: 'root'
如果你想在根模块以外的任何模块中provide
服务,那么你最好在功能模块的装饰器中使用providers
数组,否则你会受到循环依赖的困扰。这里有趣的讨论 - https://github.com/angular/angular-cli/issues/10170
答案 0 :(得分:22)
如果使用providedIn,则注入为Module的提供者,而不将其添加到模块的提供者。
来自Docs
服务本身是CLI生成的类 用@Injectable装饰。默认情况下,配置此装饰器 使用providedIn属性,该属性为服务创建提供程序。 在这种情况下,提供:' root'指定服务应该是 在根注入器中提供。
答案 1 :(得分:11)
providedIn: 'root'
是自Angular 6以来提供服务最简单,最有效的方法:
有关更多信息,请考虑阅读documentation和NgModule FAQs
顺便说一句:
答案 2 :(得分:4)
providedIn告诉Angular根注入器负责创建您的Service实例。通过这种方式提供的服务会自动提供给整个应用程序使用,不需要在任何模块中列出。
服务类可以充当其自己的提供程序,这就是为什么在@Injectable装饰器中定义它们是您所需的全部注册。
答案 3 :(得分:3)
请参阅@Nipuna的出色解释,
我想通过添加示例来扩展它。
如果您仅使用不带providedin
属性的Injectable装饰器,例如
@Injectable()
然后,您将不得不在相应模块的providers
数组中写入服务的名称。
像这样;
data.service.ts↴
import { Injectable } from '@angular/core';
@Injectable()
export class DataService {
constructor() {}
// Code . . .
}
app.module.ts↴
import { AppComponent } from './app.component';
import { DataService } from './core/data.service';
@NgModule({
declarations: [AppComponent],
providers: [DataService], // ⟵ LOOK HERE WE PROVIDED IT
imports: [...],
bootstrap: [AppComponent],
})
export class AppModule {}
但是,如果您使用providedIn: 'root'
,如下所示:
data.service.ts↴
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class DataService {
constructor() {}
// Code . . .
}
然后我们的模块如下所示:
app.module.ts↴
import { AppComponent } from './app.component';
import { DataService } from './core/data.service';
@NgModule({
declarations: [AppComponent],
providers: [],
imports: [...],
bootstrap: [AppComponent],
})
export class AppModule {}
看到我这次没有在DataService
数组中添加providers
,因为不需要。
答案 4 :(得分:1)
在@Injectable()元数据中注册提供者也可以 Angular通过从已编译的服务中删除服务来优化应用程序 应用程序(如果未使用)。
答案 5 :(得分:0)
来自文档
什么是可注射装饰器?
将一个类标记为可用于Injector进行创建。
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class UserService {
}
服务本身是CLI生成的类,并用@Injectable()装饰。
provideIn到底能做什么?
通过将其与@NgModule或其他InjectorType关联,或通过指定应在“根”注入器中提供此注入物来确定将提供可注射物的注入器,在大多数应用程序中它将是应用程序级注入器
providedIn: Type<any> | 'root' | null
providedIn:“ root”
当您在根级别提供服务时,Angular会创建一个共享的服务实例,并将其注入到任何需要该服务的类中。在@Injectable()元数据中注册提供程序还允许Angular通过从未编译的应用程序中删除服务来优化应用程序。
providedIn:模块
也可以指定在特定的@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 {
}