如何在 Angular 中使用 @Injectable 装饰器
介绍
以下哪些关于@Injectable装饰器的陈述对您来说有效?
- 应该向每个服务添加@Injectable装饰器。
- 任何使用依赖注入(DI)的服务都应添加@Injectable装饰器。
- 如果您不使用“providedIn”选项,则不必添加@Injectable 装饰器。
- @Injectable装饰器与 'providedIn' 选项一起意味着该服务不应添加到模块的提供者数组中。
正确答案是 2 和 4。要找出原因,请继续阅读本指南,我们将在其中讨论@Injectable装饰器及其对 Angular 中的 DI 的影响。
Angular 带有自己的 DI 框架,用于设计 Angular 应用以增强其模块化和效率。@Injectable()是任何 Angular 服务定义的重要组成部分。有些人可能会选择上述问题的错误答案,原因是他们错误判断了@Injectable装饰器和 Angular 中的 DI之间的关系,没有理解这个装饰器真正的作用。
添加 @Injectable 并不代表注册服务
对于用于 DI 的控制反转 (IOC) 容器,通常需要两个东西。第一个是令牌。要向 IOC 容器注册某些东西,令牌是必需的。令牌是注册任何服务的唯一东西。第二个是提供者。提供者可帮助 DI 容器创建特定依赖项的实例。
在 Angular 中,使用令牌注册服务并将其传递给提供者可以通过两种不同的方式完成。
首先,可以使用特定的@NgModule注册服务。注册过程是通过将服务传递给提供程序数组来进行注册。在本例中,使用的令牌是 TypeScript 类型MyService。这里的提供程序是useClass 。此提供程序策略通知可以通过new ... ()来启动某个依赖项。
@NgModule({
...
providers: [
// long hand syntax
{provide: MyService, useClass: MyService},
// short hand syntax
MyService
],
})
由于令牌和提供者之间存在相似性,您可以在此处使用简写语法。
注意:还有几个其他位置,例如@NgModule,您可以在其中添加提供程序数组的服务。注册的想法相当于@Components和@Directives。
使用providedIn选项是注册服务的另一种方式。
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() { }
}
那么@Injectable 怎么样?
我还没有正确描述@Injectable装饰器。原因是@Injectable装饰器与向容器注册服务无关。那么@Injectable装饰器的用途是什么?
确实, MyService可以有一些依赖项,这是标准做法。例如,您可以使用HttpClient。
import { HttpClient } from '@angular/common/http';
@Injectable()
export class MyService {
constructor(private httpClient: HttpClient) { }
}
让我们试着理解当需要获取MyService实例时会发生什么。当 Angular 需要创建服务时,它应该向其传递一个HttpClient实例。那么它该怎么做呢?
首先,Angular 应该知道提到了哪个依赖项。还记得您使用令牌来注册依赖项吗?使用相同的令牌,您可以向 Angular 请求该依赖项的实例。因此,Angular 将调查构造函数并查看是否为令牌HttpClient请求了服务。如果使用该令牌注册了服务,Angular 可以使用该令牌启动MyService并提供它创建的实例。
var MyService = /** @class */ (function () {
function MyService(httpClient) {
this.httpClient = httpClient;
}
MyService = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Injectable"])(),
__metadata(
"design:paramtypes",
[_angular_common_http__WEBPACK_IMPORTED_MODULE_1__["HttpClient"]]
)
], MyService);
return MyService;
}());
这里重要的部分是 Angular 没有使用@Injectable装饰器来注册服务。
结论
在 Angular 中使用 DI 时, @Injectable装饰器与每项服务相关但并非必不可少。但是,我承认这个问题有些误导,因为介绍中的选项 2 —“应将 @Injectable 装饰器添加到使用 DI 的任何服务” — 并不是理想的表述方式。它意味着服务具有自己的依赖项。此外,无论如何,最好始终包含一个装饰器。省略它通常没有什么好处。如果您稍后添加依赖项,可能会遇到一些奇怪的错误。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~