请参阅@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 {}
请参阅我这次没有在providers 数组中添加DataService,因为它不需要。
良好做法
这可能会派上用场,来自Angular Guides
在服务的@Injectable 装饰器中使用应用根注入器提供服务。
为什么? Angular 注入器是分层的。
为什么?当您将服务提供给根注入器时,该服务的实例是共享的,并且在需要该服务的每个类中都可用。当服务共享方法或状态时,这是理想的选择。
为什么?当您在服务的 @Injectable 装饰器中注册服务时,优化工具(例如 Angular CLI 的生产构建使用的工具)可以执行树抖动并删除未使用的服务通过您的应用。
为什么?当两个不同的组件需要不同的服务实例时,这并不理想。在这种情况下,最好在需要新的独立实例的组件级别提供服务。