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