Angular 6:为'root'

时间:2018-05-07 09:38:06

标签: angular typescript service injectable angular6

随着您在AppModule中提供服务的Angular 5更改为Angular 6,您在@Injectable装饰器中设置'provideIn'键我已将所有服务更改为使用新的“provideIn”方法。但是,例外是我的拦截服务。

如何为'root'提供HTTP_INTERCEPTORS标记并使用InterceptorService?

这是我使用atm的Angular 5方式:

@Injectable()
export class InterceptorService implements HttpInterceptor {
...
}
在AppModule中

providers: [{
  provide: HTTP_INTERCEPTORS,
  useClass: InterceptorService,
  multi: true
}]

但Angular 6的方式是什么?

我尝试过像

这样的东西
@Injectable({
  provideIn: 'root',
  useValue: HTTP_INTERCEPTORS,
  deps: [forwardRef(() => InterceptorService)]
})
export class InterceptorService implements HttpInterceptor {
...
}

以及许多其他使用Injectable的变体但似乎无法弄清楚如何在不将对象文字直接写入模块的提供程序的情况下使其工作。

3 个答案:

答案 0 :(得分:4)

Angular 6的provideIn - 属性只是对Angular 5中行为的补充。如果要提供已存在的InjectionToken,则仍需使用{ provide: ClassA, useClass: ClassB }语法。

参见 - > https://angular.io/guide/dependency-injection-in-action#external-module-configuration

TL; DR: 您在Angular 6中提供HTTP_INTERCEPTORS的方式没有改变,并且没有“Angular 6”。

答案 1 :(得分:2)

在拦截器中

@Injectable()
export class InterceptorService implements HttpInterceptor {
...
}

在App Module中

providers: [{
  provide: HTTP_INTERCEPTORS,
  useClass: InterceptorService,
  multi: true
}]
  

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

     

“如果无法在@Injectable装饰器中配置提供程序   服务,然后在根AppModule中注册应用程序范围的提供程序,而不是   在AppComponent中。通常,在NgModule中注册提供者而不是>在根应用程序组件中。“

此外,如果服务范围应限于应用程序的功能或分支,请在该分支/功能的顶级组件中提供该服务

https://angular.io/guide/dependency-injection-in-action

答案 2 :(得分:0)

此处需要注意的几点:

1。 providedIn: 'root'是一个不错的功能,但它可能不是为您构建的

正如@Leon所提到的那样,此功能旨在使服务更易于摇晃树。它并不意味着完全使用模块的providers: []属性来替换。此选项主要是针对库开发人员,而不是针对应用程序开发人员。

想象一下这种情况:

您在几个月前创建了一项服务,现在您的应用程序不再使用它。您知道它没有在使用它,因为它是您的应用程序,并且您具有完整的知识并可以控制代码库。您对这项服务做什么?

A)确保它正在使用providedIn: 'root',以便Angular可以将它从捆绑包中摇出来,因为您不再使用它了。

B)删除服务。

我的猜测是B!

想象另一种情况:

您正在使用npm软件包中的第三方Angular模块。该模块提供12种差异服务,您可以在应用程序中使用这些服务以利用其功能。您的应用程序不需要所有这些功能,因此您只需将其中3种服务类型注入到应用程序组件或服务中即可。

您如何解决这个问题?

A)分叉存储库,以便您可以删除应用程序不使用的所有服务,从而不必将其包括在捆绑软件中。

B)要求项目所有者使用providedIn: 'root'。如果图书馆作者使用了providedIn: 'root',那么您不使用的服务不会影响您的捆绑软件规模,它们可以保留在npm软件包/ Angular模块中,供其他团队在需要时使用。

我的猜测是B!

2。 providedIn: 'root'不适用于拦截器

拦截器是multi DI令牌服务,这意味着您可以为同一DI令牌提供多个值。该令牌为HTTP_INTERCEPTORS@Injectable({...})装饰器没有像@NgModule({...})装饰器那样公开用于提供其他标记装饰类型的api。

这意味着您无法使用Anywhere you would normally ask for 'HTTP_INTERCEPTORS' add this service to the set of values to use instead装饰器告诉Angular @Injectable({...})

您只能在@NgModule({...})装饰器中执行此操作。

3。提供拦截器取决于顺序

拦截器是一个管道,它们在事务中的顺序决定了它们访问请求对象(修改或检查)和响应对象(修改或检查)的顺序。

尽管某些拦截器可能与顺序无关,但您可能仍希望在该顺序中具有确定性。

因此,即使providedIn: 'root'为拦截器工作,提供它们的顺序也将取决于Angular编译步骤中类型的解析顺序-可能不是您想要的。

相反,将它们提供给providers: []装饰器中的@NgModule({...})数组意味着您可以显式设置调用它们的顺序。