为了账号安全,请及时绑定邮箱和手机立即绑定

装饰器在任何其他混乱“this”上下文之前调用方法

装饰器在任何其他混乱“this”上下文之前调用方法

天涯尽头无女友 2023-07-06 19:56:02
真正的问题我想我找到了真正的问题,inversify其他一切都很好。在原来的帖子中,我省略了部分代码,因为我认为它们不是造成问题的原因。在我的ICitiesRepo实现中,我有一个方法ensureDb确保初始化一些typeorm属性,因为这个方法必须是异步的,我不能只在构造函数中调用它,所以应该在任何 CRUD 操作之前调用它,然后我创建了一个具有以下目的的装饰器ensureDb在类中的任何其他方法之前调用:  export const ensureCall = (method: string) => {    return (target: any) => {      for (const prop of Object.getOwnPropertyNames(target.prototype)) {        if (prop === method || prop === 'constructor') continue;        const originalMethod = target.prototype[prop];        if (originalMethod instanceof Function) {          target.prototype[prop] = async (...args: any[]) => {            await target.prototype[method]();            return originalMethod.apply(this, args);          };        }      }    };  };这就是用途:   @ensureCall('ensureDb')   @injectable()   class CitiesRepo implements ICitiesRepo {       @inject('CitiesWriteRepo') private readonly repo: IWriteRepo<City>;              async ensureDb() {          await this.repo.doSomething();          // repo is undefined because I messed up with the context       }          // interface implementation   }ensureDb如果我删除该装饰器并在其他方法之前调用它就可以工作:   const container = getContainer();   const citiesRepo: ICitiesRepo = container.get('CitiesRepo');   await citiesRepo.ensureDb();   const list = await citiesRepo.getAll(); // It works是否有可能解决这个问题或其他更好的方法来实现我想做的事情?原帖我有一个带有通用存储库的项目,但在使用 inversifyJS 注入存储库对象时遇到一些问题。结构是这样的:   interface IWriteRepo<T>  { /* interface members */ }   @injectable()   class WriteRepo<City> implements IWriteRepo<City> { /* interface implementation */ }   interface ICitiesRepo { /* interface members */ }   @injectable()   class CitiesRepo implements ICitiesRepo {       @inject('CitiesWriteRepo') private readonly repo: IWriteRepo<City>;       // interface implementation   }该服务已正确注入,repo: ICitiesRepo但通用“孙子”repo: IWriteRepo<City>未定义。知道如何修复它吗?
查看完整描述

1 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

你快到了。你之所以得到这个,是undefined因为this你的装饰器中是未定义的,应该引用你的目标的实例化实例。将该定义更改为常规函数调用而不是箭头函数应该可以解决问题。


export const ensureCall = (method: string) => {

  return (target: any) => {

    for (const prop of Object.getOwnPropertyNames(target.prototype)) {

      if (prop === method || prop === 'constructor') continue;


      const originalMethod = target.prototype[prop];

      if (originalMethod instanceof Function) {

        // Regular function declaration

        target.prototype[prop] = async function(...args: any[]) {

          await target.prototype[method]();

          // Now `this` refers to an instantiated instance

          return originalMethod.apply(this, args);

        };

      }

    }

  };

};


查看完整回答
反对 回复 2023-07-06
  • 1 回答
  • 0 关注
  • 79 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信