angular - TypeScript dekoratori - Setter se ne poziva na svojstvu objekta


Pokušavam implementirati TypeScript dekoratore za pohranu podataka u localstorage u Angular aplikaciji. Ovo je ono što pokušavam postići

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

I koristi ga ovako: Komponenta 1:

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

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

Komponenta 2:

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

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

Dakle, koliko ja razumijem, seter svojstva se poziva samo kada postoji neka dodjela samom objektu, a ne njegovom svojstvu. Stoga ovo funkcionira,

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

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

Ali ovo će na neki način pobiti svrhu koju pokušavam postići ovdje. Dakle, pitanje je, kako mogu modificirati dekorator funkciju da bih to mogao učiniti?

this.userSession.val = 'some val';

Bilo kakvi savjeti su dobrodošli.

Odgovor #1

Ne koristim dekoratore na ovaj način, ali prilično sam siguran da morate izbrisati svojstvo da biste ga zamijenili, pa promijenite ovo:

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

Za ovo (omatanje s brisanjem):

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