我们使用装饰器为Angular中的类声明、方法、访问器、属性和参数提供元数据。我们使用它来装饰组件、指令、模块等。在本文中,让我们了解什么是装饰器,为什么需要它,以及如何创建自定义装饰器。我们还要了解Angular支持的内置装饰器。
Angular 装饰器
Angular 装饰器是一个函数,我们使用它将元数据附加到类、方法、访问器、属性或参数。
我们以@expression形式使用装饰器,其中expression是装饰器的名称。
例如,@Component是一个装饰器,我们将其附加到一个Angular组件。当Angular看到@Component装饰器应用于一个类时,它将该类视为一个组件类。在下面的示例中,正是@Component装饰器使AppComponent成为一个Angular组件。如果没有装饰器,AppComponent就像其他类一样。
1 2 3 4 5
| @Component({ }) export class AppComponent { title = 'app'; }
|
decorator装饰器是一个Typescript特性,它仍然不是Javascript的一部分。它仍处于提案阶段。
要启用Angular 装饰器,我们需要将experialDecorators添加到tsconfig.json文件中。ng-new命令会自动为我们添加此内容。
1 2 3 4 5 6 7
| { "compilerOptions": { "target": "ES5", "experimentalDecorators": true } }
|
创建新的装饰器
在下面的例子中,我们创建了一个函数simpleDecorator。我们将使用它来装饰AppComponent类。该函数不接受任何参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import { Component, VERSION } from '@angular/core'; @simpleDecorator @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { name = 'Angular ' + VERSION.major; constructor() { console.log('Hello from Class constructor'); } ngOnInit() { console.log((this as any).value1); console.log((this as any).value2); } } function simpleDecorator(target: any) { console.log('Hello from Decorator'); Object.defineProperty(target.prototype, 'value1', { value: 100, writable: false }); Object.defineProperty(target.prototype, 'value2', { value: 200, writable: false }); } **** Console *** Hello from Decorator Hello from Class constructor 100 200
|
正如我们前面所说,d装饰器 是一个常规的JavaScript函数。由于我们在类上使用它,因此它获取AppComponent的实例作为参数(目标)
1 2 3 4 5
| function simpleDecorator(target: any) { console.log('Hello from Decorator');
|
在函数内部,我们将两个自定义属性value1和value2添加到AppComponent。请注意,我们使用defineProperty属性向组件类添加一个新属性。此外,我们将其添加到类的原型属性中。
1 2 3 4 5 6 7 8 9 10
| Object.defineProperty(target.prototype, 'value1', { value: 100, writable: false }); Object.defineProperty(target.prototype, 'value2', { value: 200, writable: false });
|
现在,我们可以使用它来装饰我们的AppComponent
1 2 3 4 5 6 7
| @simpleDecorator @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent {
|
在组件内部,我们可以使用关键字“this”访问新的属性。
1 2 3 4
| ngOnInit() { console.log((this as any).value1); console.log((this as any).value2); }
|
带参数的装饰器
要创建一个带参数的装饰器,我们需要创建一个工厂函数,该函数返回装饰器函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import { Component, VERSION } from '@angular/core'; @simpleDecorator({ value1: '100', value2: '200' }) @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { name = 'Angular ' + VERSION.major; constructor() { console.log('Hello from Class constructor'); } ngOnInit() { console.log((this as any).value1); console.log((this as any).value2); } } function simpleDecorator(args) { console.log(args); return function(target: any) { console.log('Hello from Decorator'); console.log(typeof target); console.log(target); Object.defineProperty(target.prototype, 'value1', { value: args.value1, writable: false }); Object.defineProperty(target.prototype, 'value2', { value: args.value2, writable: false }); }; }
|
simpleDecorator将args作为参数,并返回 装饰器函数。除了使用参数填充财产之外,其余代码与上面的代码相同。
1 2 3 4
| function simpleDecorator(args) { console.log(args); return function(target: any) {
|
我们在组件上应用simpleDecorator,如下所示
Angular 装饰器 列表
Angular提供了几个内置的装饰器。我们可以把它们分为四类
以下是Angular中装饰器的完整列表。
- 类装饰器
- @NgModule
- @Component
- @Injectable
- @Directive
- @Pipe
- 属性装饰器
- @Input
- @Output
- @HostBinding
- @ContentChild
- @ContentChildren
- @ViewChild
- @ViewChildren
- 方法装饰器
- 参数装饰器
- @Inject
- @Self
- @SkipSelf
- @Optional
- @Host
类装饰器