| Autor | Zpráva | ||
|---|---|---|---|
| weroro Profil |
#1 · Zasláno: 19. 1. 2023, 01:33:33
Zdravím,
snažím sa o vytvorenie akejsi reaktívnej triedy za pomoci Proxy. Narazil som však na problém, ktorý nedokážem vyriešiť a ani vygoogliť. Moja myšlienka je na dnešnú dobu prostá. Vedieť sledovať stav fieldov v inštancii nejakej mojej triedy. Podobne ako to má Angular, že ak v rámci triedy zmením nejakú premennú, tak sa vykoná nejaká akcia. Momentálny funkčný stav, avšak nie pre mňa uspokojivý je tento: class ProxyTest {
constructor() {
Object.setPrototypeOf(this, new Proxy(Object.create(this.constructor.prototype), {
set: (target, property, value) => {
console.log('proxy:', value);
target[property] = value;
return true;
},
})
)
this.web = 'DJPW';
setTimeout(() => {
this.web = 'Jak psát web';
}, 2000);
}
}
const proxyTest = new ProxyTest();[console.log vypíše "proxy: DJPW"] a sleduje zmeny všetkých fieldov konštruktoru. Po 2 sekundách, sa zmení hodnota sledovaného fieldu (simulácia nejakej asynchrónnej akcie - napr. fetch) a zareaguje mi na túto zmenu Proxy [console.log vypíše "proxy: Jak psát web"] .
Ja však potrebujem presunúť zadefinovanie Proxy mimo konštruktor, dokonca mimo triedu úplne. Moja predstava je v zmysle: class ProxyTest {
constructor() {
this.web = 'DJPW';
setTimeout(() => {
this.web = 'Jak psát web';
}, 2000);
}
}
const proxyTest = new ProxyTest();
Object.setPrototypeOf(proxyTest, new Proxy(Object.create(proxyTest.constructor.prototype), {
set: (target, property, value) => {
console.log('proxy:', value);
target[property] = value;
return true;
},
})
)A tu som narazil na problém, že neviem ako to dosiahnuť. Nahradením this za inštanciu proxyTest sa nič nevyriešilo a je to bez reakcie.
Mohli by ste mi prosím poradiť, prípadne mi dať iné riešnie pre dosiahnutie môjho cieľa? Ďakujem za váš čas. |
||
| Radek9 Profil |
weroro:
Problém je, že v tom druhém případě ten handler nastavuješ až ve chvíli, kdy už ta property web existuje přímo na tom objektu proxyTest. V tu chvíli na její změny ta proxy schovaná v prototypu nereaguje. Takže musíš nejdřív tu property smazat, potom nahradit prototyp a teprve potom ji tam znovu přidat, aby se propsala do té proxy:
const proxyTest = new ProxyTest()
let web = proxyTest.web
delete proxyTest.web
Object.setPrototypeOf(
proxyTest,
new Proxy(Object.create(proxyTest.constructor.prototype), {
set: (target, property, value) => {
console.log('proxy:', value);
target[property] = value;
return true;
},
})
)
proxyTest.web = webObecněji pro všechny properties by se to dalo napsat takhle: const proxyTest = new ProxyTest()
let props = Object.entries(proxyTest)
for (let [key] of props) {
delete proxyTest[key]
}
Object.setPrototypeOf(
proxyTest,
new Proxy(Object.create(proxyTest.constructor.prototype), {
set: (target, property, value) => {
console.log('proxy:', value);
target[property] = value;
return true;
},
})
)
for (let [key, val] of props) {
proxyTest[key] = val
} |
||
| weroro Profil |
#3 · Zasláno: 19. 1. 2023, 14:10:26
Radek9:
Vynikajúce. Veľmi pekne ti ďakujem. Aj za vysvetlenie. Ja som experimentoval s podobným riešením ako si dal ty, ale neúspešne. Teraz už viem prečo. Ja som totiž nezmazal originálne properties, tak som bol v tom, že sa jedná o nefunkčný postup. |
||
|
Časová prodleva: 3 roky
|
|||
0