【问题标题】:TypeScript class decorator that modifies object instance修改对象实例的 TypeScript 类装饰器
【发布时间】:2016-12-30 14:36:28
【问题描述】:

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

  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 框架)。

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

【问题讨论】:

    标签: class typescript decorator aurelia instances


    【解决方案1】:

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

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

    【讨论】:

    • 希望我早点看到这个 - 我花了几个小时才想出这个。
    【解决方案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)

    【讨论】:

      猜你喜欢
      • 2021-05-15
      • 1970-01-01
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      • 2016-07-13
      • 1970-01-01
      • 2017-11-15
      相关资源
      最近更新 更多