Angular 将传统参数传递给角度组件内的方法装饰器

Angular 将传统参数传递给角度组件内的方法装饰器,angular,typescript,decorator,angular-decorator,Angular,Typescript,Decorator,Angular Decorator,假设我们有很多方法,我们想在原始方法中添加一个确认对话框。因此,我们决定建立一个定制的装饰 @Component({...}) export class HeroComponent { constructor(private dialog: MatDialog) {} @confirmByDialog(this.dialog) deleteHero() { ... } } 但这种方法不起作用,因为 无法读取未定义(hero.component.ts)的属性“dialog” 如何

假设我们有很多方法,我们想在原始方法中添加一个确认对话框。因此,我们决定建立一个定制的装饰

@Component({...})
export class HeroComponent {
  constructor(private dialog: MatDialog) {}

  @confirmByDialog(this.dialog)
  deleteHero() { ... }
}

但这种方法不起作用,因为

无法读取未定义(hero.component.ts)的属性“dialog”

如何将附加参数传递给装饰器?我已经考虑过将
对话框
传递给原始函数本身,通过
args
访问它,但这听起来像是一个非常肮脏的黑客行为


提前谢谢

您无法访问decorator参数中的实例字段。装饰器应用于类而不是实例

简单的解决方案是传入对话框字段的名称,但这意味着该字段需要是公共的

您还需要更改转发参数和
的方式。因为我们需要访问传入的实际数据,所以不能使用箭头函数,我们需要使用
apply
来转发

class HeroComponent {
  constructor(public dialog: MatDialog) { }

  @confirmByDialog("dialog") // Checked by the compiler.
  deleteHero() { }
}
function confirmByDialog<K extends string>(dialog: K) {
  return (target: Record<K, MatDialog>, key: string, descriptor: any) => {
    const originalMethod: Function = descriptor.value;

    descriptor.value = function (this: Record<K, MatDialog>, ...args: any[]) {
      const dialogRef = this[dialog].open(ConfirmationDialogComponent);
      return dialogRef
        .afterClosed()
        .subscribe((confirmed: boolean) => {
          if (confirmed) {
            originalMethod.apply(this, ...args);
          }
        });
    };
    return descriptor;
  };
}
class组件{
构造函数(公共对话框:MatDialog){}
@confirMyDialog(“dialog”)//由编译器检查。
deleteHero(){}
}
功能确认对话框(对话框:K){
返回(目标:记录,键:字符串,描述符:任意)=>{
const originalMethod:Function=descriptor.value;
descriptor.value=函数(this:Record,…args:any[]){
const dialogRef=此[dialog]。打开(确认对话框组件);
返回对话框REF
.afterClosed()
.订阅((已确认:布尔)=>{
如果(已确认){
原始方法。应用(此,…args);
}
});
};
返回描述符;
};
}

您无法访问decorator参数中的实例字段。装饰器应用于类而不是实例

简单的解决方案是传入对话框字段的名称,但这意味着该字段需要是公共的

您还需要更改转发参数和
的方式。因为我们需要访问传入的实际数据,所以不能使用箭头函数,我们需要使用
apply
来转发

class HeroComponent {
  constructor(public dialog: MatDialog) { }

  @confirmByDialog("dialog") // Checked by the compiler.
  deleteHero() { }
}
function confirmByDialog<K extends string>(dialog: K) {
  return (target: Record<K, MatDialog>, key: string, descriptor: any) => {
    const originalMethod: Function = descriptor.value;

    descriptor.value = function (this: Record<K, MatDialog>, ...args: any[]) {
      const dialogRef = this[dialog].open(ConfirmationDialogComponent);
      return dialogRef
        .afterClosed()
        .subscribe((confirmed: boolean) => {
          if (confirmed) {
            originalMethod.apply(this, ...args);
          }
        });
    };
    return descriptor;
  };
}
class组件{
构造函数(公共对话框:MatDialog){}
@confirMyDialog(“dialog”)//由编译器检查。
deleteHero(){}
}
功能确认对话框(对话框:K){
返回(目标:记录,键:字符串,描述符:任意)=>{
const originalMethod:Function=descriptor.value;
descriptor.value=函数(this:Record,…args:any[]){
const dialogRef=此[dialog]。打开(确认对话框组件);
返回对话框REF
.afterClosed()
.订阅((已确认:布尔)=>{
如果(已确认){
原始方法。应用(此,…args);
}
});
};
返回描述符;
};
}