MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Definirea Evenimentelor Personalizate

Capacitatea de a genera evenimente programatic ne deschide calea către crearea de evenimente personalizate - putem defini și declanșa evenimente arbitrare.

De exemplu, avem o funcție constructor Account, care acceptă o sumă de bani și creează un cont monetar condițional:

function Account(money) {
   _money = money;
   this.pay = function(sum) {
       if(_money >= sum) {
           _money -= sum;
           console.log(_money);
       }
   }
}

În variabila _money este stocată suma curentă de bani din cont. Cu funcția pay cheltuim condiționat o anumită sumă, dacă balanța permite. Dar, să presupunem că trebuie să notificăm sistemul când are loc o retragere de fonduri. Pe de o parte, am putea face acest lucru direct în metoda pay - să apelăm console.log() în metodă și să afișăm un text pe consolă.

Dar în momentul scrierii acestui cod, s-ar putea să nu fim siguri ce text exact trebuie afișat pe consolă. Sau poate fi nevoie să nu afișăm pe consolă, ci în fereastra browserului. Sau să trimitem notificarea la o resursă de rețea anumită. Sau poate funcția noastră constructor va fi folosită în Node.js, unde poate fi necesară o altă prelucrare.

Și poate că alți dezvoltatori vor folosi funcția noastră constructor, care ar putea avea propriul lor înțeles despre ce trebuie făcut la retragerea fondurilor. În orice caz, ne confruntăm cu multivarianță, dar în toate aceste situații, principalul lucru pe care trebuie să-l facem este să notificăm sistemul că a avut loc o retragere de fonduri.

Și pentru a acoperi toate aceste situații, ne va ajuta definirea propriilor evenimente.

Pentru definirea evenimentelor personalizate, putem utiliza constructorul Event, în care se transmite numele evenimentului. Deci, să luăm în considerare următorul program:

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <title>FDC.COM</title>
</head>
<body>
   <button id="btn">Pay</button>
   <script>
   const button = document.getElementById("btn");
   const myAcc = new Account(100); // contul monetar condițional
   // stabilim handler-ul pentru evenimentul payment pentru întregul document
   document.addEventListener("payment", () => console.log("Payment succeeded!"));

   // la apăsarea butonului, executăm metoda pay
   button.addEventListener("click", () => myAcc.pay(50));
   // constructorul obiectului cont
   function Account(money) {
       _money = money;
       this.pay = function(sum) {
           if(_money >= sum) {
               _money -= sum;
               console.log(_money);

               const event = new Event("payment"); // definim obiectul evenimentului
               document.dispatchEvent(event);      // generăm evenimentul pentru întregul document
           }
       }
   }
   </script>
</body>
</html>

Aspecte principale. În metoda pay, creăm un obiect Event care va reprezenta evenimentul "payment" (nu contează că un astfel de eveniment nu există inițial, noi îl creăm). Apoi generăm acest eveniment:

const event = new Event("payment"); // definim obiectul evenimentului
document.dispatchEvent(event);      // generăm evenimentul pentru întregul document

De menționat că evenimentul este generat pentru întregul document: document.dispatchEvent(event), dar acesta poate fi orice element specific al paginii web.

Pentru a procesa acest eveniment, ne abonăm la el:

document.addEventListener("payment", () => console.log("Payment succeeded!"));

Din nou, abonarea la eveniment se face pentru întregul document. Handler-ul evenimentului doar afișează un șir pe consolă.

La apăsarea butonului, apelăm metoda pay a obiectului myAcc și astfel generăm evenimentul "payment" (dacă pe cont sunt suficiente fonduri).

Pentru a testa, apăsați pe buton.

De asemenea, la fel ca în cazul general, putem obține obiectul evenimentului în handler:

// obținem obiectul evenimentului prin parametrul e
document.addEventListener("payment", (e) => {
   console.log(e.type);                //  payment
   console.log("Payment succeeded!");
});

CustomEvent

Cu toate că tipul Event poate fi utilizat, acesta nu este foarte potrivit pentru definirea evenimentelor personalizate. De exemplu, ce se întâmplă dacă dorim să transmitem în handler-ul evenimentului informații suplimentare - suma retrasă, soldul curent sau altceva? Pentru astfel de cazuri, este mai bine să utilizăm tipul CustomEvent. Să modificăm codul JavaScript în modul următor:

const button = document.getElementById("btn");
document.addEventListener("payment", (e) => {
   console.log("Payment succeeded!");
   console.log("Payment Sum:", e.detail.paymentSum);   // obținem datele evenimentului
   console.log("Current balance:", e.detail.balance);
});

const myAcc = new Account(100);
// la apăsarea butonului, executăm metoda pay
button.addEventListener("click", () => myAcc.pay(50));

function Account(money) {
   _money = money;
   this.pay = function(sum) {
       if(_money >= sum) {
           _money -= sum;
           // definim obiectul evenimentului
           const event = new CustomEvent("payment", {
               detail: {                //  transmitem date despre eveniment în CustomEvent
                   paymentSum: sum,
                   balance: _money
               }
           });
           document.dispatchEvent(event);      // generăm evenimentul pentru întregul document
       }
   }
}

În CustomEvent, ca al doilea parametru, se transmite un obiect de configurare, care are proprietatea detail. Această proprietate, la rândul său, reprezintă un obiect cu un set arbitrar de proprietăți. În acest caz definim în el proprietățile paymentSum și balance și le transmitem valorile care ne interesează:

const event = new CustomEvent("payment", {
   detail: {
       paymentSum: sum,
       balance: _money
   }
});

Apoi transmitem obiectul CustomEvent (la fel ca și Event) în dispatchEvent și astfel generăm evenimentul:

document.dispatchEvent(event);

La procesarea evenimentului, putem obține datele transmise prin proprietatea detail:

document.addEventListener("payment", (e) => {
   console.log("Payment succeeded!");
   console.log("Payment Sum:", e.detail.paymentSum);   // obținem datele evenimentului
   console.log("Current balance:", e.detail.balance);
});

Exemplu de afișare în consolă la prima apăsare a butonului:

Payment succeeded!
Payment Sum: 50
Current balance: 50

În mod similar, putem defini și alte evenimente. De exemplu, să definim un alt eveniment pentru cazul în care nu sunt suficiente fonduri pentru efectuarea plății:

const button = document.getElementById("btn");
document.addEventListener("payment_success", (e) => {
   console.log("Payment succeeded!");
   console.log("Payment Sum:", e.detail.paymentSum);
   console.log("Current balance:", e.detail.balance);
});
document.addEventListener("payment_fail", (e) => {
   console.error("Payment failed");
   console.error("Current balance:", e.detail.balance, "Requested Sum: ", e.detail.paymentSum);
});
const myAcc = new Account(100);
button.addEventListener("click", () => myAcc.pay(50));

function Account(money) {
   _money = money;
   this.pay = function(sum) {
       const data = {
           paymentSum: sum,
           balance: _money
       };
       if(_money >= sum) {
           _money -= sum;

           const event = new CustomEvent("payment_success", {
               detail: data
           });
           document.dispatchEvent(event);
       } else {
           const event = new CustomEvent("payment_fail", {
               detail: data
           });
           document.dispatchEvent(event);
       }
   }
}

Acum, dacă sunt suficiente fonduri în cont, se generează evenimentul "payment_success", iar dacă nu, se generează "payment_fail". Pentru fiecare dintre aceste evenimente definim propriul nostru handler.

Afișarea în consolă a programului (la trei apăsări ale butonului):

Payment succeeded!
Payment Sum: 50
Current balance: 100
Payment succeeded!
Payment Sum: 50
Current balance: 50
Payment failed
Current balance: 0 Requested Sum: 50
← Lecția anterioară Lecția următoare →