深入理解 Angular 中的装饰器(二)

上一篇文章 中,为大家介绍了 Typescript 中装饰器(Decorator)的概念及基本的声明方式。让读者对装饰器有一个基础的了解,本文将深入揭示装饰器的用法。

装饰器的分类

在 Typescript 中,装饰器按装饰的目标对象可分为:

  1. 类装饰器
  2. 方法装饰器
  3. 访问器装饰器
  4. 方法参数装饰器
  5. 属性装饰器

下面就为读者分别介绍这些装饰器的用法。

类装饰器

类装饰器是可以用在类的声明上,在编译时,装饰器函数被执行,会将目标类的构造函数作为参数传入,利用 prototype 属性,我们可以为一个类加入在声明以外的属性和方法。代码示例如下:

声明一个装饰器:

1
2
3
4
5
6
7
8
9
function init(who: string) {
return function(target: any): any {
target.prototype.who = 'Tom'

target.prototype.sayHello = function() {
return `I am ${who}`;
}
}
}

在装饰器函数中,我们为目标类加入了一个名为 who 的属性和一个名为 sayHello 的方法。 下面我们声明类:

1
2
3
4
5
6
7
@init('Tom')
class Hello {

constructor() {
}

}

我们声明了一个类 Hello, 并用 init 装饰器进行了修饰。现在 Hello 这个类中就多了 who 这个属性和 sayHello 这个方法,并且 who 的值被赋值为 “Tom”。

下面试试使用这个类:

1
2
let hello = Hello();
console.log(hello.sayHello());

如果你在IDE(比如: VSCode)中输入以上的代码, 你会发现IDE会提示”Property ‘sayHello’ does not exist on type ‘Hello’ “的错误,如果直接使用 tsc 进行编译也一样提示错误。错误的原因在于我们通过装饰器添加上去的属性或方法,对于编译器来说是不存在的,为了处理这个问题,我们引入一个函数:

1
2
3
function HelloClassFactory(): Hello & { who: string, sayHello: Function} {
return new Hello() as Hello & {who : string, sayHello: Function}
}

在函数中,我们转换了 Hello 类,增加了属性声明。 把最终使用 Hello 类的代码改为一下内容:

1
2
let hello = HelloClassFactory();
console.log(hello.sayHello());

现在我们可以编译并运行程序了。

实际上,Angular 中的 Component, Service 这些装饰器用的原理就是类似这样的。

下一步

下一步,我们将向大家展示方法的装饰器(Decorator)

本文标题:深入理解 Angular 中的装饰器(二)

文章作者:晨星

发布时间:2019年07月07日 - 14:07

最后更新:2020年09月16日 - 08:09

原始链接:https://www.mls-tech.info/web/angular/angular-typescript-decorator-2/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。