TypeScript 装饰器 - 未在对象的属性上调用 Setter

Posted

技术标签:

【中文标题】TypeScript 装饰器 - 未在对象的属性上调用 Setter【英文标题】:TypeScript Decorators - Setter not called on property of an object 【发布时间】:2018-05-02 05:59:04 【问题描述】:

我正在尝试实现 TypeScript 装饰器,用于在 Angular 应用程序的本地存储中存储数据。这就是我想要实现的目标

export function Cache() 

    return function (target, key): any 
        // property value
        let _val = target[key];

        // property getter
        const getter = function () 
            const data = localStorage.get(key);
            if (data) 
                return data;
            
            localStorage.set(key, _val);
            return _val;
        ;

        // property setter
        const setter = function (newVal) 
            localStorage.set(key, newVal);
            console.log('Setting',newVal);
            _val = newVal;
        ;

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

并像这样使用它: 组件 1:

....
@Cache() userSession: any = val:'';

ngOnInit() 
    this.userSession.val = "some val"
  
....

组件 2:

....
@Cache() userSession: any;

ngOnInit() 
    console.log('Stored value is',this.userSession);
    // expected : val:'some val'
    // prints : val:''

....

所以据我了解,只有在对对象本身而不是属性进行任何分配时才调用属性设置器。因此这是可行的,

Object.assign(this.userSession , val: 'some val');
or
this.userSession = val: 'some val'

console.log(this.userSession) // prints: val: 'some val'

但这会比我在这里想要达到的目的。所以问题是,我如何修改装饰器功能才能做到这一点?

this.userSession.val = 'some val';

任何指针表示赞赏。

【问题讨论】:

【参考方案1】:

我没有以这种方式使用装饰器,但我很确定您需要删除该属性才能替换它,因此请更改此:

    Object.defineProperty(target, key, 
        get: getter,
        set: setter,
        enumerable: true,
        configurable: true
    );

对此(用删除包装):

if (delete this[key]) 
    Object.defineProperty(target, key, 
        get: getter,
        set: setter,
        enumerable: true,
        configurable: true
    );

【讨论】:

这不是问题。如果存在,则无需删除现有属性。在这种情况下,它甚至不存在。问题是访问是嵌套的。

以上是关于TypeScript 装饰器 - 未在对象的属性上调用 Setter的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 素描 - 装饰器

从0开始的TypeScriptの十二:装饰器

从0开始的TypeScriptの十二:装饰器

TypeScript 装饰器的执行原理

关于何时在 TypeScript 中调用装饰器的困惑

typeScript 装饰器