Dekoratory manipulowania elementem dom

0

pseudokod:

@hook(".selector")
class selectorHook {
 @onInput valueChanged(value) {
  console.log(`value changed to ${value}`);
 }
}

wie ktoś jak ogarnąć implementację dekoratorów, tak aby onInput operował na .selector?

0

To jakiś konkretny framework, czy po prostu dekoratory w TypeScript?

0

@LukeJL:

LukeJL napisał(a):

To jakiś konkretny framework, czy po prostu dekoratory w TypeScript?

dekoratory w TypeScript

0

Hmm, chcesz zrobić coś takiego, że masz klasę i dekorator z nazwą jakiegoś selektora.

Jak dasz dekorator na metodę, to użycie jej w obiekcie użyje tej z dekoratora.
Jak podłączysz się pod element querySelectorem z tą nazwą selektora, to nie można tak bezpośrednio dać tam tej metody, bo ona należy do obiektu lub obiekt by musiał być jakoś globalnie dostępny, bo każdy moduł co zaimportuje tę klasę to stworzy sobie nową.
Potem drugie hooki to by musiały pod dane selektory używać np. nazw metod jako eventów addEventlistener('nazwa_metody', funkcja_z_hooka).

Dekorator na classie pozwala zmodyfikować klasę przed konstruktorem, więc można np. dodać pole z twoim selectorem i np. classa mogła by dziedziczyć po jakiejś abstrakcyjnej co by potem korzystała z tych podmapowanych selektorów przez dekoratory

Ogólnie to jest dosyć czasochłonne, zrobiłem sobie jakieś proste tego typu na DOM, to w miarę łatwo jak globalnie się te obiekty gdzieś podmapuje.
Jeszcze jak się korzysta z innych frameworków to one mogą się odświeżać i referencję trzeba jakoś trzymać do aktualnego obiektu.

Mógłbyś jeszcze mieć jakiś jeden globalny singleton i te hooki po prostu dodawały by do niego co byś potrzebował, tak w sumie działają frameworki jak flask, fastapi.

Wzór dekoratora:

function hook(selector: string) {
  return function(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
    const orgFunc = descriptor.value;

    descriptor.value = function (...args: any[]) { // można by było bez tych linii
      console.log("hook before"); // bo funkcja i tak nie miała być modyfikowana 
      orgFunc.apply(this, args); //
      console.log("hook after"); //
    } //
    
    document.querySelector(selector)?.addEventListener(propertyKey, (e) => {
      descriptor.value();
    });
    
    return descriptor;
  }
}

class Example {
  @hook('.input-class')
  change() {
    console.log("change event");
  }
}

<input class='.input-class' />


1

A co chcesz zrobić? Jakiś wrapper na DOM, żeby można było zdefiniować klasę, która reprezentuje selektor, a metody reprezentują handlery zdarzeń (które będą podłączane za pomocą dekoratora onInput zapewne do eventu input?).

czyli w VanillaDOM to coś takiego by wyglądało?

const el = document.querySelector(".selector");
el.addEventListener('input', e => {
   console.log(`value changed to ${e.target.value}`);
});

Moim zdaniem dekoratory wydają się trochę na siłę w tym przypadku. Bo to, o co chodzi, to po prostu o to, żeby mieć dane selektora w metodach. Kiedyś ludzie nie potrzebowali dekoratorów do tego, tylko tworzyli klasę i w konstruktorze ustawiali selektor. A teraz wszystko się robi na dekoratorach, bo taka moda (nie mówię, że dekoratory są złe, tylko że są nadużywane chyba na zasadzie czystej fascynacji nimi).

Ale nawet bez klas można by coś podobnego zrobić:

function hook(sel, events) {
    const el = document.querySelector(".selector");
    Object.entries(events).forEach(([name, func]) => {
        el.addEventListener(name, func);
    });
}

hook('.selector', {
   click: e => {
       e.target.style.color = 'red';
   }
});

ale wracając do podejścia z dekoratorami... pobawiłem się trochę tym i takie rozwiązanie mniej więcej mi wyszło:

function hooks(selector) {
    return {
        onInput() {
            // kod tworzący dekorator (mamy też dostęp do selector!)
        },
        onClick() {
        }
    }
}

const {onInput} = hooks('.selector');

class Foo {
    @onInput() foo(e) {
        
    }
}

czyli tworzysz w domknięciu ileś dekoratorów naraz (w zasadzie tworzysz ileś fabryk dekoratorów naraz). Wtedy miałyby dostęp do selektora.

0

rozwiązania fajne :D ale mi nie leżą xD
zależy mi na zachowaniu mojej logiki, o ile to możliwe :P nie chodzi o modę. Mógłbym porzucić to rozwiązanie na rzecz fromEvent z rxjs i też będzie dobrze xD ale jak sobie coś ubzduram to łatwo o tym nie zapominam

0

Angular, albo NestJS do swoich dekoratorów wykorzystują bibliotekę reflect metadata, ale nie pokażę przykładu, bo przez 20 minut nie udało mi się stworzyć niczego sensownego :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1