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 = web Obecně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: 2 roky
|
0