Angular @Injectable 注解的工作原理浅析
下面是 SAP 电商云 Spartacus UI 两个 Angular Service 类,都加上了 @Injectable
的注解,区别就在于是否具有输入参数 providedIn
:
@Injectable() 装饰器指定 Angular 可以在 DI 系统中使用这个类。 这个注解的输入元数据,providedIn: ‘root’,意味着被注解的 Angular service 类,在整个应用程序中都是可见的。
当将服务(提供者)注入到我们的组件/服务中时,通过构造函数中的类型定义来指定我们需要的提供者。下面是一个例子:
import { Component } from '@angular/core';
import { Http } from '@angular/http';
@Component({
selector: 'example-component',
template: '<div>I am a component</div>'
})
class ExampleComponent {
constructor(private http: Http) {
// use `this.http` which is the Http provider
}
}
这里的类型定义是 Http(注意大写的 H),Angular 会自动将其分配给 http。
对于 JavaScript 开发人员来说,上面的工作方式或许有些神奇。类型定义是特定于 TypeScript 的,所以我们编译的 JavaScript 代码理论上应该不知道在浏览器中运行它时我们的 http 参数是什么。
在我们的 tsconfig.json 文件中,我们将 emitDecoratorMetadata 设置为 true。 这会将有关参数类型的元数据发送到我们编译的 JavaScript 输出中的装饰器中。
让我们看看上面列举的 TypeScript 代码,实际上被编译成什么(为了清楚起见,我保留了 ES6 导入):
import { Component } from '@angular/core';
import { Http } from '@angular/http';
var ExampleComponent = (function() {
function ExampleComponent(http) {
this.http = http;
}
return ExampleComponent;
})();
ExampleComponent = __decorate(
[
Component({
selector: 'example-component',
template: '<div>I am a component</div>',
}),
__metadata('design:paramtypes', [Http]),
],
ExampleComponent
);
从这里,我们可以看到编译后的代码,知道 http 就是 @angular/http 提供的 Http 服务 - 它被添加为我们的类的装饰器:
__metadata('design:paramtypes', [Http]);
所以本质上,@Component 装饰器被转换为普通的 ES5,并且一些额外的元数据通过 __decorate 赋值提供。 这反过来告诉 Angular 查找 Http 令牌并将其作为第一个参数提供给组件的构造函数 - 将其分配给 this.http:
function ExampleComponent(http) {
this.http = http;
}
相关文章
- [Angular] Create a custom validator for reactive forms in Angular
- [Angular] Subscribing to the valueChanges Observable
- [Angular 2] NgNonBindable
- [Angular] $q.all()
- Angular的依赖注入(依赖反转)原理说明
- [Angular] Communicate Between Components Using Angular Dependency Injection
- [Angular2 Form] Create and Submit an Angular 2 Form using ngForm
- [Angular 2] Order Dynamic Components Inside an Angular 2 ViewContainer
- Angular Universal 应用避免 SSR hang 的一些指导方针
- SAP Spartacus 中 Angular json pipe 的工作原理
- Angular getOrCreateInjectable的实现原理调试
- Angular 指令ngTemplateOutlet的运行原理单步调试
- Angular ngIf 指令的工作原理
- Event handling in Angular
- 使用 Angular Transfer State 的一个具体例子
- 一个关于Angular Directive selector里的中括号使用问题
- SAP UI5和Angular的函数防抖(Debounce)和函数节流(Throttle)实现原理介绍
- Angular ngIf 指令运行时执行原理
- Angular jasmine spyOn函数的实现原理
- Angular @Hostbinding工作原理
- Angular 自定义 structural 指令的一个例子
- 使用Angular rxjs打印鼠标点击事件的x坐标之和
- Angular getOrCreateInjectable的实现原理调试
- Angular依赖注入的一个例子和注入原理单步调试
- SAP Spartacus 中 Angular json pipe 的工作原理
- 使用Angular HTTP client对数据模型进行删除操作
- Angular FormBuilder的工作原理
- Angular应用的入口