2016-12-30 83 views
4

我正在为奥里利亚一个插件,需要一个类装饰器打字稿类装饰修饰对象实例

  1. 增加属性到新的对象实例,并
  2. 调用新对象的外部函数作为论据。

我已经通过实例看,到目前为止,我已经把(“伪十岁上下的”代码)

return function addAndCall(target: any): any { 
    var original = target; 

    var newConstructor = function (...args) { 
     original.apply(this, args); 
     this.newAttribute = "object instance value"; 
     ExternalModule.externalFunction(this); 
    }; 

    newConstructor.prototype = Object.create(original.prototype); 
    newConstructor.prototype.constructor = original; 

    return <any>newConstructor; 
} 

  • 我不完全清楚的这里的细节(或实际需要的)和
  • 它可能无法正常工作,因为我使用此装饰器从类实例化对象时发生Aurelia错误(并且我怀疑它是我的装饰器而不是Aurelia框架是越野车)。

任何帮助和解释将不胜感激!

回答

2

为什么不直接分配这些属性的原型,随后分配到该实例在第一次调用

// decorator 
function addAndCall(cb: Function, newField: string) { 
    // cb is now available in the decorator 
    return function(ctor: Function): void { 

    Object.defineProperty(ctor.prototype, newField, { 
     value: function(...args: any[]) { 
     return Object.defineProperty(this, newField, { 

      value: function(...args: any[]) { 
      console.log(newField, ...args); 
      } 

     })[newField](...args); 
     } 
    }); 
    cb(ctor); 
    } 
} 

let callMe = (decoratedCtor) => console.log(decoratedCtor); 
@addAndCall(callMe, 'propertyName') 
class AddToMe {} 

let addToMe = new AddToMe(); 
(<any>addToMe).propertyName(1, 2); 
+0

愿望我早就看到了这个 - 花了我数小时才想出来。 –

1

这里有一个工作版本:

function addAndCall(target: any) { 
    var original = target; 

    function construct(constructor, args) { 
     var c: any = function() { 
      this.newAttribute = "object instance value"; 
      ExternalModule.externalFunction(this); 
      return constructor.apply(this, args);; 
     } 

     c.prototype = constructor.prototype; 
     return new c(); 
    } 

    var f: any = function (...args) { 
     return construct(original, args); 
    } 

    f.prototype = original.prototype; 
    return f; 
} 

code in playground