首页 > 解决方案 > 使用装饰器将类方法附加到窗口对象

问题描述

我正在将 VueJS 与 typescrpit 一起使用,但这可以在任何 js 框架中。

我有一些我想全局公开的方法的组件,以便可以通过浏览器控制台使用它们。第一个想法是将它们附加到窗口对象。这可以通过我们安装在我的案例中的生命周期方法来完成,但我更喜欢使用装饰器来编写和使用更简洁的解决方案。

我试过类似的东西:

mycomponenet.ts:

function makeGlobal() {
   return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
     (window as any)[propertyKey] = () => target[propertyKey]();
   };
 }

然后这个装饰器将很容易使用,例如:

@makeGlobal()
myMethodToGoGloabl(){
// do stuff ...
}

直到现在一切正常,直到函数使用"this"如下:

@makeGlobal()
myMethodToGoGloabl(){
  this.firstName = "";
}

然后我得到一个未定义的错误名字。我通过搜索和阅读了解到装饰器是在类实例化之前执行的,因此我暴露的(如果我错了,请纠正我)是一个原型方法,而不是实例的方法,为什么我们无法访问它。我尝试绑定(this),但失败的原因与我没有全局公开实例的方法相同。

有没有办法在我的情况下使用装饰器,或者它们在这里没用?

标签: javascripttypescriptdecorator

解决方案


猜猜问题是你的装饰师。你根本不接管这个实例......而且你这样做的方式,你将无法传递参数。

建议:

function makeGlobal() {
   return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
     var currentThis = this;
     (window as any)[propertyKey] = () => target[propertyKey].apply(currentThis, args);
   };
 }

还要记住克里斯蒂安在评论中所说的话。它基本上只能用于单例,因为它将覆盖多个实例的方法


推荐阅读