Skapa en egenskapshämtare och inställare med TypeScript-dekorator


Jag vill skapa en egenskapsgetter och -setter med TypeScript-dekorator men jag sitter fast på att definiera funktionen som ska köras när egenskapen ändras eller efterfrågas.

Om jag har följande användning av min Field.watch-dekorator:

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

och dekoratörens implementation är:

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

Jag får ett fel på @Field.watch({onSet: this.resetCssCache}) som säger att this inte är definierad.

Jag antar att dekoratören tolkas på definitionsnivå och inte på instansnivå. Finns det ett sätt att binda en icke-statisk metod till onSet-egenskapen hos min dekoratör?

Svar #1

Du kan inte komma åt en metod genom this inuti en dekoratör, du kan skicka metoden med prototype:

export class Test {

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

    public resetCssCache() {

    }

}

Observera att detta betyder att när du anropar watchers.onSet(newVal, this['_' + key]);, så kommer this inuti resetCssCache faktiskt att vara watchers och inte instansen av Test. Du bör anropa det med call så att du kan skicka this uttryckligen watchers.onSet.call(this, newVal, this['_' + key])

Svar #2

Din antagelse om vad 'detta' representerar är felaktig. Det verkar som att du letar efter dekoratörer på instansnivå, som du påpekade i den sista meningen av din fråga.

Jag hade ett liknande behov tidigare, detta problem gav svaret.

Denna fråga ger också en lösning.

Lycka till! ;-)

Relaterade artiklar