You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Angular中多类场景下装饰器的应用及多装饰器映射规则咨询

Angular类装饰器的应用规则与多类/多装饰器场景说明

嘿,我来帮你理清楚Angular里类装饰器的这些规则——其实核心逻辑和TypeScript的原生装饰器机制完全一致,Angular只是基于它做了业务层面的封装~

装饰器与类的映射规则

装饰器和类的绑定完全靠位置关系:你写的装饰器必须紧挨着目标类的上方(中间可以有空行,但不能插入其他类、函数或无关代码),它就会作用于这个紧邻的类。

举个直观的代码例子:

// 自定义组件装饰器
function CustomComponent(options: { selector: string }) {
  return (target: Function) => {
    console.log(`装饰了组件类: ${target.name},选择器是${options.selector}`);
  };
}

// 自定义指令装饰器
function CustomDirective(options: { selector: string }) {
  return (target: Function) => {
    console.log(`装饰了指令类: ${target.name},选择器是${options.selector}`);
  };
}

// 这个类会被CustomComponent修饰
@CustomComponent({ selector: 'app-home' })
export class HomeComponent { }

// 这个类会被CustomDirective修饰
@CustomDirective({ selector: '[appTooltip]' })
export class TooltipDirective { }

// 空行不影响映射关系,这个类依然会被CustomDirective修饰
@CustomDirective({ selector: '[appResize]' })

export class ResizeDirective { }

简单说:不管文件里有多少装饰器和类,每个装饰器只作用于它正下方的那个类,完全是一对一的紧邻绑定。

同一文件中使用多个装饰器的规则

当然允许!而且有两种常见场景:

1. 多个装饰器修饰同一个类

你可以给单个类叠加多个装饰器,执行顺序是从下到上(或者说从右往左)。比如:

function LogClass() {
  return (target: Function) => {
    console.log(`记录类信息: ${target.name}`);
  };
}

function AddMetadata(key: string, value: any) {
  return (target: Function) => {
    Reflect.defineMetadata(key, value, target);
  };
}

// 执行顺序:先跑AddMetadata,再跑LogClass
@LogClass()
@AddMetadata('role', 'admin')
export class AdminComponent { }

在Angular项目里,你也可以把自定义装饰器和Angular内置的@Component/@Directive一起用,完全兼容。

2. 多个装饰器分别修饰不同的类

这就是最常见的场景——比如在一个文件里定义多个组件/指令,每个类对应自己的装饰器,它们之间互相独立,不会产生干扰,就像第一个例子里的HomeComponentTooltipDirective那样。

最后再提一句:Angular的所有内置装饰器(@Component@NgModule@Pipe等)本质上都是遵循TypeScript装饰器规范的,所以上面的规则对它们完全适用。

内容的提问来源于stack exchange,提问作者Deepak Patidar

火山引擎 最新活动