使用TypeScript Decorator创建属性getter和setter

时间:2018-04-17 12:09:20

标签: typescript decorator

我想用TypeScript Decorator创建一个属性getter和setter,但我仍然坚持定义在更改或请求属性时要运行的函数。

如果我对Field.watch装饰器有以下用法:

export class Test {
   ...
   @Field.watch({onSet: this.resetCssCache})
   public layoutId = 0;
   ...
   public resetCssCache() {
      ...
   }
   ...
}

和装饰器实现是:

export class Field {

    public static watch(watchers: { onGet?: () => any, onSet?: (newValue: any, oldValue: any) => any }): Function {
        return (target: any, key: string) => {

            // property getter
            const getter = function() {
                return this['_' + key];
            };

            // property setter
            const setter = function(newVal) {
                if (watchers.onSet) {
                    this['_' + key] = watchers.onSet(newVal, this['_' + key]);
                }
                this['_' + key] = newVal;
            };

            // Delete property.
            if (delete this[key]) {

                // Create new property with getter and setter
                Object.defineProperty(target, key, {
                    get: getter,
                    set: setter,
                    enumerable: true,
                    configurable: true
                });
            }
        }
    }
}

我在@Field.watch({onSet: this.resetCssCache})上收到错误,告知this未定义。

我猜装饰器是在定义级别解释而不是在实例级别解释。 有没有办法将非静态方法绑定到我的装饰器的onSet属性上?

2 个答案:

答案 0 :(得分:1)

您无法通过装饰器内的this访问方法,您可以使用prototype传递方法:

export class Test {

    @Field.watch({onSet: Test.prototype.resetCssCache })
    public layoutId = 0;

    public resetCssCache() {

    }

}

请注意,这意味着当您致电watchers.onSet(newVal, this['_' + key]);时,this内的resetCssCache实际上将watchers而不是Test的实例。您应该使用call来调用它,以便明确this

传递watchers.onSet.call(this, newVal, this['_' + key])

答案 1 :(得分:0)

您对'this'代表的假设是不正确的。您正在寻找实例级装饰器,正如您在问题的最后一句中指出的那样。

我过去有类似的需求,issue提供了答案。

issue也提供了解决方案。

祝你好运! ; - )