IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

5. diel - Tvorba OOP diáre v JavaScripte

V minulej lekcii, Referenčnej a hodnotové dátové typy v JavaScripte , sme si vysvetlili rozdiely medzi hodnotovými a referenčnými dátovými typy. Už vieme, že keď uložíme inštanciu triedy do nejakej premennej, je v nej v skutočnosti uložené referencie (odkaz) na túto inštanciu. Môžeme tak používať jednu inštanciu z niekoľkých premenných alebo ju jednoducho odovzdávať, bez toho aby sa skopírovala.

Ako som sľúbil, v dnešnom tutoriálu objektovo orientovaného programovania v JavaScripte začneme programovať elektronický diár. Využijeme tu tiež znalosti z minulej lekcie.

Príprava

Najskôr sa ale zamyslíme nad tým, čo všetko budeme potrebovať. Vytvoríme si jednoduchú stránku, index.html, s formulárom na pridanie záznamu hore a výpisom záznamov dole. Do nejakého kontajnera, napr. Do elementu <div>, si vložíme dva input. Budú typu "text" a "date" na názov úlohy a jeho dátum. Nakoniec ešte pridáme tlačidlo na potvrdenie. Nižšie pridáme druhý <div> na zoznam úloh.

Čo sa týka JavaScriptu, môžeme si vytvoriť zložku js/ a v nej tri skripty: Diar.js, Zaznam.js a obsluha.js. Rovno je v našej stránke aj naodkazujeme.

Súbor index.html by teda mohol vyzerať takto:

<!DOCTYPE html>
<html lang="cs-cz">
<head>
    <meta charset="UTF-8">
    <title>Diář</title>
</head>
<body>
    <h1>Diář</h1>
    <div>
        <input type="text" id="nazev" placeholder="Vyplňte název úkolu"><br>
        <input type="date" id="datum" placeholder="Vyplňte datum"><br>
        <button id="potvrdit">Uložit úkol</button>
    </div>
    <div id="seznam-ukolu">

    </div>
    <script src="js/Diar.js"></script>
    <script src="js/Zaznam.js"></script>
    <script src="js/obsluha.js"></script>
</body>
</html>

Stránka by mohla vyzerať nasledovne:

Tvoja stránka
localhost

Vzhľad teraz nebudeme príliš riešiť.

Záznam

Začneme so súborom Zaznam.js. Ako asi tušíte, súbor bude obsahovať triedu reprezentujúci jeden záznam v našom diári. Môžeme jej teda dať rôzne vlastnosti, ktoré pri vytvorení a po vytvorení záznamu budeme môcť meniť. Zatiaľ to môže byť názov, dátum a či bol úloha splnená. Prvé dva parametre nastavíme konštruktory a čo sa týka splněnosti úlohy, tak budeme predpokladať, že je po vytvorení vždy nesplnený:

class Zaznam {

    constructor(nazev, datum) {
        this.nazev = nazev;
        this.datum = datum;
        this.splneno = false;
    }

}

Diár

Presuňme sa teraz k samotnému diári.

Konštruktor

V súbore Diar.js si vytvoríme triedu Diar s konštruktory a v ňom nadefinujeme niekoľko vlastností:

  • zaznamy - Záznamy diáre vytvoríme ako prázdne pole.
  • jazyk - Jazyk výpisu dáta (dátumov) záznamov sa nám môže v budúcnosti hodiť, pretože rôzne jazyky majú rôzne formáty. Napr. českej dátum vyzerá inak ako anglické. Pre nastavenie jazyka pridáme do konstruktoru parameter. Pretože budeme chcieť väčšinou slovenské prostredie, definujeme mu predvolenú hodnotu "cs-CZ", ktorá sa použije ak parameter nezadáme.
Trieda by zatiaľ mohla vyzerať takto:
class Diar {

    constructor(jazyk = "cs-CZ") {
        this.zaznamy = [];
        this.jazyk = jazyk;
    }

}

Vyberanie elementov na stránke

V triede budeme potrebovať pracovať s DOM elementy na stránke. Možno ste sa už stretli s princípom oddelenia práce s logikou od práce s užívateľským rozhraním. Tohto základného programátorského pravidlá využíva napr. Architektúra MVC.

V javascriptových frameworkoch, ku ktorým sa dostanete po tomto kurze, je architektúra aplikácia postavená tak, aby sa nemiešal kód vyberajúci elementy na stránke s ďalším kódom aplikácie. Bolo by to totiž veľmi neprehľadné.

My si v základnom OOP kurze nebudeme vytvárať žiadnu komplikovanú architektúru, ale budeme sa snažiť umiestniť vyberanie elementov zo stránky na jedno jediné miesto v triede. Týmto miestom bude práve konštruktor. Vytvoríme si tu niekoľko ďalších vlastností a do nich uložíme elementy zo stránky, ktoré budeme v triede ďalej potrebovať:

  • nazevInput - Input element s názvom novo pridávaného záznamu.
  • datumInput - Input element s dátumom novo pridávaného záznamu.
  • potvrditButton - Ukladacie tlačidlo.
  • vypisElement - Element pre výpis záznamov uložených v diári.

Konštruktor bude teraz vyzerať takto:

constructor(jazyk = "cs-CZ") {
    this.zaznamy = [];
    this.jazyk = jazyk;

    this.nazevInput = document.getElementById("nazev");
    this.datumInput = document.getElementById("datum");
    this.potvrditButton = document.getElementById("potvrdit");
    this.vypisElement = document.getElementById("seznam-ukolu");
}

Nikam inam v triede nebudeme ďalej vkladať žiadny ďalší výber elementov, pretože by to bolo veľmi neprehľadné.

Metódy

Prejdime k metódam diára.

NastavUdalosti ()

Aby náš konštruktor nebol príliš dlhý, vyčleníme nastavenie obslužných udalostí elementom na stránke do oddelenej metódy. V našom prípade ide len o obsluhu kliknutie na tlačidlo.

Zatiaľ si pridajme naivné implementáciu metódy pre obsluhu tlačidlá, ktorá nebude fungovať. Prečo si vysvetlíme za okamih:

nastavUdalosti() {
    this.potvrditButton.onclick = function() { // tento kód nebude fungovat
        const zaznam = new Zaznam(this.nazevInput.value, this.datumInput.value);
        this.zaznamy.push(zaznam);
        this.vypisZaznamy();
    };
}

Metóda na udalosť onclick tlačidla this.potvrditButton nadviaže obslužnú funkciu. Tu je ešte všetko v poriadku. Vnútri sa vezmú hodnoty z inputov a na ich základe sa vytvorí nový záznam. Túto novú inštanciu vložíme do poľa. Všetky záznamy potom vypíšeme.

Čo je teda zle? Ak ste dávali v Základných konštrukciách JavaScripte pozor, viete, že:

Pri použití function pre obsluhu udalostí elementov sa mení kontext a kľúčové slovo this následne ukazuje na element, ktorý udalosť spôsobil. this teda prestane obsahovať inštanciu našej triedy. Toto správanie je chyba v návrhu jazyka JavaScript a zabraňuje nám pracovať s inštančným premennými a metódami v obsluhe udalostí.

Arrow functions

Spôsobov, ako tento problém obísť, je hneď niekoľko. My si spomenieme to najjednoduchšie riešenie. Na obsluhu udalosti použijeme tzv. Arrow function, čo je "skrátený" zápis funkcie. Názov vychádza zo znaku šípky (anglicky arrow), ktorým sa tieto funkcie zapisujú. Arrow functions boli do JavaScriptu pridané až neskôr a preto chybou zmeny kontextu už netrpí. Presnejšie ani žiadny svoj kontext nemajú a kľúčové slovo this v nich obsahuje to, čo v ňom bolo predtým, bez zmeny.

Arrow function do nejakej premennej uložíme nasledujúcim spôsobom:

nazevFunkce = () => {
    // tělo funkce
}

Ak by sme chceli funkciu poslať aj parametre, môžeme ich písať do zátvoriek, ako sme zvyknutí:

nazevFunkce = (parametr) => {
    // tělo funkce
}

Ak by sme chceli poslať iba jeden, môžeme zátvorky dokonca aj vynechať:

nazevFunkce = parametr => {
    // tělo funkce
}

Teraz teda metódu nastavUdalosti() opravíme, aby v obslužnej funkcii fungovalo kľúčové slovo this. To totiž používame k prístupu k vlastnostiam našej triedy:

nastavUdalosti() {
    this.potvrditButton.onclick = () => { // this zůstane nyní stále this
        const zaznam = new Zaznam(this.nazevInput.value, this.datumInput.value);
        this.zaznamy.push(zaznam);
        this.vypisZaznamy();
    };
}

Metódu zavoláme na konci konstruktoru:

this.nastavUdalosti();

VypisZaznamy ()

V metóde pre výpis úloh nás asi nič neprekvapí, funguje veľmi podobne ako výpis zamestnancov, ktorý sme vytvárali v predošlých lekciách:

vypisZaznamy() {
    this.vypisElement.innerHTML = "";
    for (let i = 0; i < this.zaznamy.length; i++) {
        const zaznam = this.zaznamy[i];
        this.vypisElement.innerHTML += `<h3>${zaznam.nazev}</h3>kdy: ${zaznam.datum}<br>splněno: ${zaznam.splneno}`;
    }
}

Metóda zmaže všetok obsah z nášho elementu a vypíše tam postupne naše úlohy pomocou cyklu.

Obsluha

Nakoniec musíme ešte v obsluha.js vytvoriť inštanciu triedy Diar a vypísať uložené záznamy. Tie tam vo chvíli vytvorení diáre ešte nie sú, ale ďalej v kurze je budeme načítavať z lokálneho úložiska:

const diar = new Diar();
diar.vypisZaznamy();

Ak teraz našu aplikáciu spustíme v prehliadači, bude vyzerať takto:

Tvoja stránka
localhost

V prípade akýchkoľvek problémov si svoj kód porovnajte s funkčným riešením v prílohe.

V budúcej lekcii, Riešené úlohy k 4.-5. lekciu OOP v JavaScripte , sa zamyslíme nad spôsobom ukladania záznamov, aby sa nám nestratili po obnovení alebo zatvorení stránky. Reč bude o populárnom formáte JSON. Tiež naprogramujeme zoskupovanie úloh v rovnakom dni a krajšie výpis splněnosti úloh.

V nasledujúcom cvičení, Riešené úlohy k 4.-5. lekciu OOP v JavaScripte, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 673x (1.86 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Referenčnej a hodnotové dátové typy v JavaScripte
Všetky články v sekcii
Objektovo orientované programovanie v JavaScriptu
Preskočiť článok
(neodporúčame)
Riešené úlohy k 4.-5. lekciu OOP v JavaScripte
Článok pre vás napísal Šimon Raichl
Avatar
Užívateľské hodnotenie:
3 hlasov
Autor se věnuje hlavně tvorbě všemožných věcí v JS
Aktivity