角度6依赖注入

Ham*_*our 59 javascript typescript angular-cli angular angular6

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

@Injectable({
  providedIn: 'root',
})
export class HeroService {}
Run Code Online (Sandbox Code Playgroud)

但是文档仍然指的是providers在模块元数据中注册模块数组中的服务,就像我们在Angular 5中一样:

@NgModule({
  providers: [HeroService],
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

那么应该使用哪种方法使注入器知道它应该注入的服务&模块提供者的数组方法是否会被弃用?

Par*_*ain 77

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

providedIn

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

引入这种新方法可以在应用程序中实现更好的树形抖动.目前,添加到模块提供者的服务将最终出现在最终捆绑中,即使它未在应用程序中使用,这有点令人伤心.

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

  • 实际上我发现服务意识到使用它的模块很奇怪,反之亦然.这种服务如何可以重复使用?如果我添加一个需要使用该服务的新模块,我需要更改服务本身吗?这听起来很嘲笑 (5认同)

JEY*_*JEY 12

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

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

所以基本上你将providedIn: 'root'用于任何应用程序范围的服务.对于其他服务,请继续使用旧版本.

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

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

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