Angular 使用类装饰器向新属性添加装饰器
我想知道的几乎都在书名里。 我想知道如何添加一个新属性,它有自己的decorator和一个类decorator 我想创建一个类装饰器Api(string[]),它公开类装饰器中列出的类方法。 为此,我想从Angular发出一个带有Angular 使用类装饰器向新属性添加装饰器,angular,typescript,Angular,Typescript,我想知道的几乎都在书名里。 我想知道如何添加一个新属性,它有自己的decorator和一个类decorator 我想创建一个类装饰器Api(string[]),它公开类装饰器中列出的类方法。 为此,我想从Angular发出一个带有EventEmitter的事件,为此,我必须将@Output()装饰器添加到一个新属性中 我可以吗 下面是一个示例:我只是有一个MyClass,其中包含process、open和close方法。 我想创建decorator(s?)来公开我想要的任何方法(这里是open和
EventEmitter
的事件,为此,我必须将@Output()
装饰器添加到一个新属性中
我可以吗
下面是一个示例:我只是有一个MyClass,其中包含process、open和close方法。
我想创建decorator(s?)来公开我想要的任何方法(这里是open和close)。我想象了一个类装饰器,它添加了api
属性和一个方法装饰器来公开一个方法,也许吧
class MyClass {
@Output() api = new EventEmitter();
$exposedMethods: object = {};
constructor() {
this.$exposedMethods = {
open: this.open.bind(this),
close: this.close.bind(this)
};
this.api.emit(this.$exposedMethods);
}
process() {
}
open() {
// stuff...
}
close() {
// stuff...
}
}
好的,所以请做好准备,因为这是一个很难掌握的概念 这里有现场演示: 守则:
从'@angular/core'导入{Component,Input,Output,EventEmitter};
const Expose:(方法:string[])=>ClassDecorator=(方法)=>{
返回组件=>{
for(const方法中的方法){
const eventEmitterName=`${method}发射器`;
prototype[eventEmitterName]=新的EventEmitter();
const outputFactory=输出(方法);
const orgFn=组件.原型[方法];
component.prototype[方法]=(…参数)=>{
orgFn(…args);
prototype[eventEmitterName].emit();
}
outputFactory(component.prototype,eventEmitterName);
}
}
}
@组成部分({
选择器:“你好”,
模板:`Emit a open event`,
样式:[`h1{font-family:Lato;}`]
})
@公开(['open']))
导出类HelloComponent{
@Input()名称:string;
开(){
log('单击按钮,现在发出事件');
}
ngOnInit(){}
}
类装饰器是函数。在您的例子中,这是一个类装饰器工厂:您提供了参数,它应该返回一个类装饰器。这是您可以看到的签名:
const Expose: (methods: string[]) => ClassDecorator = (methods) => { ... }
它声明Expose
为返回类装饰器的工厂。您的工厂接受方法列表作为参数
现在,这个工厂需要返回一个类装饰器。类装饰器是将组件本身作为唯一参数的函数。这是电话线
return component => { ... }
它返回一个符合ClassDecorator
签名的函数
之后,您需要重写每个方法。因此,您将使用一个简单的循环对其进行循环
在循环中,我们将创建一个新的事件发射器。为了简单起见,我们将使用名称[method]Emitter
。所以我们从创造圣名开始:
const eventEmitterName = `${method}Emitter`;
完成后,我们将其绑定到组件的原型:
component.prototype[eventEmitterName] = new EventEmitter();
现在有了事件发射器
之后,您需要将输出装饰器绑定到它。如果您按照前面的步骤操作,您将了解输出实际上也是一个工厂。这意味着它返回一个MethodDecorator
函数,其签名为
(component, methodKey) => { ... }
(还有第三个参数叫做描述符,但您不需要它,所以我将忽略它)
一旦知道这一点,我们将获取我们的方法的工厂结果:
const outputFactory = Output(method);
这将创建一个以您的方法命名的输出(这里是open
)
完成后,我们将重写给定的方法,在其处理完成时发出事件
这是基本的JS函数重写:
const orgFn = component.prototype[method];
component.prototype[method] = (...args) => {
orgFn(...args);
component.prototype[eventEmitterName].emit();
}
在最后一行,我们通过先前创建的事件发射器发射事件
现在,我们所要做的就是将这个事件发射器绑定到我们的组件。为此,我们只需调用由输出工厂创建的方法decorator
outputFactory(component.prototype, eventEmitterName);
现在,你的装饰师已经完成并开始工作了。正如您在stackblitz上看到的,正在运行open
函数中的代码,然后一旦运行,将运行应用程序组件模板中(open)
输出的代码
瞧好的,所以做好准备,因为这是一个非常难理解的概念
这里有现场演示:
守则:
从'@angular/core'导入{Component,Input,Output,EventEmitter};
const Expose:(方法:string[])=>ClassDecorator=(方法)=>{
返回组件=>{
for(const方法中的方法){
const eventEmitterName=`${method}发射器`;
prototype[eventEmitterName]=新的EventEmitter();
const outputFactory=输出(方法);
const orgFn=组件.原型[方法];
component.prototype[方法]=(…参数)=>{
orgFn(…args);
prototype[eventEmitterName].emit();
}
outputFactory(component.prototype,eventEmitterName);
}
}
}
@组成部分({
选择器:“你好”,
模板:`Emit a open event`,
样式:[`h1{font-family:Lato;}`]
})
@公开(['open']))
导出类HelloComponent{
@Input()名称:string;
开(){
log('单击按钮,现在发出事件');
}
ngOnInit(){}
}
类装饰器是函数。
在您的例子中,这是一个类装饰器工厂:您提供了参数,它应该返回一个类装饰器。这是您可以看到的签名:
const Expose: (methods: string[]) => ClassDecorator = (methods) => { ... }
它声明Expose
为返回类装饰器的工厂。您的工厂接受方法列表作为参数
现在,这个工厂需要返回一个类装饰器。类装饰器是将组件本身作为唯一参数的函数。这是电话线
return component => { ... }
它返回一个符合ClassDecorator
签名的函数
之后,您需要重写每个方法。因此,您将使用一个简单的循环对其进行循环
在循环中,我们将创建一个新的事件发射器。为了简单起见,我们将使用名称[method]Emitter
。因此,我们从创造神圣的世界开始