javascript - Hur tilldelar man korrekt en egenskap till funktionsomfång?
Jag har nyligen experimenterat med Typescript-dekoratorer för att försöka lösa ett "problem" jag har inom min applikation. Jag använder en JS-brygga för att skicka TS-kod till både Android och iOS, och för tillfället deklarerar vi funktioner på detta sätt:
index.js
import foo from './bar'
global.App = function() {
this.foo = foo;
};
Ovanstående kommer att göra foo-funktionen tillgänglig på den inhemska sidan av bryggan
Jag ville skriva en dekoratör att använda på den foo-metoden som skulle "registrera" sig själv på global.App men jag har misslyckats med den uppgiften.
Här är dekoratören som fungerar:
export const Task = (target, propertyKey, descriptor) => {
let originalMethod = descriptor.value;
descriptor.value = (...args) => originalMethod.apply(target, args);
if (!global.App) {
global.App = function () {
this.foo = descriptor.value;
};
}
return descriptor;
}
Hur skulle jag kunna lägga till en annan metod till den funktionen global.App?
Svar #1
För det första läggs foo-metoden endast till en gång eftersom första gången dekoratorn anropas definieras global.App och grenen som lägger till foo till global.App aldrig återinträds.
För det andra skulle global.App och foo skrivas över varje gång och inte bevaras genom upprepade anrop till dekoratorn.
Att lägga till en annan gren som hanterar att lägga till metoden efter det första anropet och dynamiskt tilldelar namnet på metoden, som jag tror ges till dekoratorn i propertyKey, skulle tillåta flera metoder att läggas till.
export const Task = (target, propertyKey, descriptor) => {
let originalMethod = descriptor.value;
descriptor.value = (...args) => originalMethod.apply(target, args);
if (!global.App) {
global.App = function () {
this[propertyKey] = descriptor.value;
};
} else {
global.App[propertyKey] = descriptor.value;
}
return descriptor;
}
Något sådant här kan fungera.
Svar #2
Efter att ha vandrat runt på SO ett tag har jag hittat en kringgående lösning för detta... kanske saknar jag kunskap om TS/JS för att veta exakt vad jag ville göra här, men i alla fall, min lösning var att registrera varje uppgift som är dekorerad och sedan på index.js hämtar jag dessa uppgifter och registrerar dem på global.App-funktionen.
Något liknande detta
task.ts
export const TaskRegistry = {};
export const Task = (target, propertyKey, descriptor) => {
const originalMethod = descriptor.value;
descriptor.value = (...args) => originalMethod.apply(target, args);
TaskRegistry[propertyKey] = descriptor.value;
return descriptor;
};
index.js
// eslint-disable-next-line func-names
global.App = function () {
// eslint-disable-next-line consistent-this
const self = this;
Object.keys(TaskRegistry).forEach((key) => {
self[key] = TaskRegistry[key];
});
}
