修改对象实例的TypeScript类装饰器

时间:2016-12-30 14:36:29

标签: class typescript decorator aurelia instances

我正在为Aurelia制作一个插件,需要一个类装饰器

  1. 将属性添加到新对象实例和
  2. 使用新对象作为参数调用外部函数。
  3. 我已经看了一些例子,到目前为止我已经把它们放在了一起(“伪代码”代码)

    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 个答案:

答案 0 :(得分:5)

为什么不将这些属性分配给原型,然后在第一次调用时分配给实例

// 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);

答案 1 :(得分:2)

这是一个有效的版本:

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