66

在 Angular 6 的最新版本中,使用providedIn服务元数据中的属性在模块中注册服务:

@Injectable({
  providedIn: 'root',
})
export class HeroService {}

然而,文档仍然提到providers在模块元数据中的模块数组中注册服务,就像我们在 Angular 5 中所做的那样:

@NgModule({
  providers: [HeroService],
})
export class AppModule {}

所以,

  • 应该使用哪种方法让注入器知道它应该注入的服务?
  • 模块providers数组方法会被弃用吗?
4

5 回答 5

88

基本上你可以使用任何一个,但根据新的 CLIprovideIn将在创建时自动添加service

#providedIn

现在有一种新的推荐方法来直接在@Injectable()装饰器中注册提供者,使用新的 providedIn 属性。它接受'root'作为应用程序的值或任何模块。当你使用 时'root',你的可注入将在应用程序中注册为单例,你不需要将它添加到根模块的提供者中。同样,如果您使用providedIn: UsersModule,则可注入对象将注册为 的提供者,而 UsersModule无需将其添加到模块的提供者中。

引入了这种新方法以在应用程序中进行更好的 tree-shaking。目前,添加到模块提供者的服务最终会出现在最终捆绑包中,即使它没有在应用程序中使用,这有点令人遗憾。

有关更多信息,请参阅此处

于 2018-05-07T07:12:11.963 回答
14

与往常一样,当有多种解决方案可用时,这取决于您想要实现的目标。但是文档为您提供了一些选择指令。

有时不希望始终在应用程序根注入器中提供服务。也许用户应该明确选择使用该服务,或者应该在延迟加载的上下文中提供该服务。在这种情况下,提供者应该与特定的 相关联@NgModule class,并且将由包含该模块的任何注入器使用。

因此,基本上您将providedIn: 'root'用于任何应用程序范围内的服务。对于其他服务,请继续使用旧版本。

不要忘记,您已经可以选择以不同的方式提供服务。例如,也可以在组件级别声明 Injectable(这在 V6 中没有改变)。

  @Component({
    selector: 'app-my-component',
    templateUrl: './my.component.html',
    providers: [ MyService ]
  })

这样,服务仅在MyComponent其子组件树中可用。

于 2018-05-07T07:09:02.570 回答
1

如果您使用 Angular 5+ 开发人员,它会在声明为 providedIn: 'root' 时自动创建可注入服务,在这种情况下,您不需要在 app.module.ts 中导入服务。您可以直接在另一个组件中使用它。

于 2018-11-01T10:20:43.543 回答
0

和装饰器具有提供者元数据选项@NgModule()@Component()您可以在其中为 NgModule 级或组件级注入器配置提供者。

@Injectable() 装饰器具有 providedIn 元数据选项,您可以在其中使用根注入器或特定 NgModule 的注入器指定装饰服务类的提供者。

在您的情况下,由于它已在“根”级别提供,因此无需再次将其添加为模块中的提供者。

更多关于依赖注入的信息

于 2019-01-20T22:13:19.087 回答
0

当我们使用providedIn: 'root' 属性时,@injectable我们不需要进入提供者的数组。

通过使用providedIn将有利于 tree shakable 功能。

Tree shakable 特性在不使用时删除了生产时未使用的依赖项。

于 2020-01-01T04:45:42.247 回答