6. diel - Objekty, JSON a vylepšenia diáre v JavaScripte
V predchádzajúcom cvičení, Riešené úlohy k 4.-5. lekciu OOP v JavaScripte, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V minulej lekcii, Riešené úlohy k 4.-5. lekciu OOP v JavaScripte , sme začali programovať náš diár v JavaScripte. V dnešnom tutoriále objektovo orientovaného programovania v ňom budeme pokračovať. Pozrieme sa na formát JSON a lokálne úložisko dát.
JSON
JSON je skratka z J ava S Cripta O bject N otation a zjednodušene by sa dalo povedať, že JSON je javascriptový objekt zapísaný ako textový reťazec. Objekty prevedenej do JSON môžeme jednoducho ukladať do súborov alebo iných úložísk a potom je z nich spätne načítať. Okrem XML je to tiež obľúbený formát pre tzv. API, kedy sa naša aplikácia spýta servera na nejaké dáta a server jej je pošle práve ako objekty vo formáte JSON.
Ukážka syntaxe
Predstavme si, že máme nejakú inštanciu, napr. Konkrétneho užívateľa s menom a vekom. Tú by sme vytvorili napr. Takto (za predpokladu, že má trieda príslušný konštruktor):
const simon = new Uzivatel("Šimon", 19);
Ak by sme túto inštanciu previedli na JSON, vyzeral by JSON nasledovne:
{ "jmeno": "Šimon", "vek": 19 }
Objekt sa v JSON definuje zloženými zátvorkami. Nasleduje názov vlastností, potom dvojbodka a ich hodnota.
Za poslednou hodnotou v bloku sa nepíše čiarka. Niektoré JS enginy s ňou totiž môžu mať problém.
Obrovskou výhodou JSON je, že je priamo súčasťou jazyka JavaScript.
Nepotrebujeme teda žiadne knižnice a akonáhle dáta z JSON otvoríme, máme
ich k dispozícii rovno ako objekty. Pokiaľ JSON vyššie teda uložíme do
premennej, bude v nej naozaj objekt s vlastnosťami jmeno
a
vek
:
const simon = { "jmeno": "Šimon", "vek": 19 }; document.write(`${simon.jmeno}, ${simon.vek}`);
Skript do stránky naozaj vypíše dáta z JSON:
Nejedná sa však o inštanciu triedy Uzivatel
,
JSON objekty sú totiž tzv. Anonymné objekty. Formát JSON
nepodporuje metódy objektov au vlastností podporuje len dátové typy
string
, number
, object
,
boolean
, null
a array
. Ide teda iba o
dáta, nie o objekty obsahujúce akúkoľvek logiku.
Podobné anonymné objekty môžete občas v JavaScripte stretnúť, používajú sa na miestach, kde by sa z nejakého dôvodu nevyplatilo deklarovať plnohodnotnú triedu. Metódy sa im dajú potom aj ďalej dodať v JavaScript kódu, nikdy ale priamo v JSON súboroch. Určite by sme anonymný objekty nemali používať namiesto štandardných inštancií.
Ukážme si ešte jeden zložitejšie JSON, v ktorom využijeme vnorené objekty a polia:
{ "jmeno": "Šimon", "vek": 19, "dovednosti": ["programování", "grafika", "plavání"], "automobil": { "spz": "13ABC", "abs": true }, "manzelka": null }
JSON vyššie definuje okrem mena a veku užívateľa aj jeho zručnosti, automobil a manželku. Ide stále o definíciu dát jednej konkrétnej inštancie. Pole zapisujeme na rozdiel od objektov do hranatých zátvoriek. Všimnite si vnoreného objektu reprezentujúci automobil. Manželku Šimon zatiaľ nemá. Opäť si všimnite chýbajúcich čiarok za poslednými hodnotami v blokoch.
Parsovanie JSON
JSON však často nezískame takto pekne zapísaný v JS súboru, ale príde
nám v textovom reťazci. Takýto JSON načítame pomocou metódy
JSON.parse()
. Ukážme si príklad s užívateľom, kedy JSON už
zapíšeme len ako text:
const simon = JSON.parse(`{ "jmeno": "Šimon", "vek": 19 }`); document.write(`${simon.jmeno}, ${simon.vek}`);
Výstup je opäť rovnaký ako v minulej ukážke:
Prevod objektu do JSON
A ako naopak prevedieme nejaký náš objekt do JSON stringu? K tomu slúži
metóda JSON.stringify()
. Vytvorme si naozaj triedu
Uzivatel
, nech máme kompletný ukážku:
class Uzivatel { constructor(jmeno, vek) { this.jmeno = jmeno; this.vek = vek; } pozdrav() { alert("Ahoj!"); } }
Metódu pozdrav()
sme do triedy vyššie pridali preto, aby sme
si overili, že v JSON naozaj nebude. Vytvorme inštanciu triedy
Uzivatel
a preveďte ju do JSON stringu:
const simon = new Uzivatel("Šimon", 19); const json = JSON.stringify(simon); document.write(json);
Náš objekt sa vypíše ako JSON:
Vidíme, že tu nie je informácia z akej triedy bol používateľ vytvorený
a tiež tu chýba všetka jeho logika. Kód je na jednom riadku, pretože v
predvolenom správaní JSON.stringify()
šetrí miestom a biele
znaky do výsledného reťazca nevkladá.
LocalStorage
Záznamy nášho diára by sme už do JSON uložiť zvládli. K ich uloženie budeme používať localStorage. To je úložisko v internetovom prehliadači používateľa (preto local), do ktorého sa môžu ukladať dáta v textovom reťazci, ku ktorým môžeme neskôr pristupovať. K dispozícii máme pre našu aplikáciu 10MB priestoru, čo je pre texty naozaj veľa
Použitie úložiska nám v našej aplikácii pomôže vyriešiť tzv. Perzistenciu dát. Po znovunačítanie stránky sa nám teraz naše záznamy samozrejme stratí. Práve preto budeme prevádzať naše polia záznamov na JSON, ktorý uložíme do localStorage a pri načítaní stránky ho naparsujeme z úložiska späť na pole. Dáta teda v aplikácii zostanú.
Práca s localStorage
S localStorage sa pracuje veľmi jednoducho. Na uloženie
nejakého reťazca pod textový index použijeme metódu setItem()
.
Analogicky, pre prečítanie hodnoty pod kľúčom, použijeme
getItem()
.
Pre kľúč "vlastnost"
nastavíme string
"data"
:
localStorage.setItem("vlastnost", "data");
Teraz vypíšeme čo je pod kľúčom "vlastnost"
, čím
získame hodnotu "data"
:
document.print(localStorage.getItem("vlastnost"));
výsledok:
Úprava diáre
Konečne teda môžeme prejsť k záveru dnešnej lekcie a diár upraviť
tak, aby sa dáta ukladala a načítala z / do localStorage
. Naše
pole zaznamy
triedy Diar
budeme ukladať jednoducho
pod kľúčom "zaznamy"
.
Konštruktor
Namiesto vytvorenia prázdneho poľa so záznamami v konstruktoru diára teda záznamy načítame z local storage
constructor(jazyk = "cs-CZ") { const zaznamyZeStorage = localStorage.getItem("zaznamy"); this.zaznamy = zaznamyZeStorage ? JSON.parse(zaznamyZeStorage) : []; this.jazyk = jazyk; this.nazevInput = document.getElementById("nazev"); this.datumInput = document.getElementById("datum"); this.potvrditButton = document.getElementById("potvrdit"); this.vypisElement = document.getElementById("seznam-ukolu"); this.nastavUdalosti(); }
Do premennej zaznamyZeStorage
vyberieme naše záznamy z
localStorage
. Ďalej musíme skontrolovať, ak nejaké záznamy
uložené vôbec sú. Ak nie, premenná zaznamyZeStorage
nadobudne
hodnoty null
. Preto tu máme ternárne
operátor, vďaka ktorému vlastnosti zaznamy
nastavíme buď
naparsované poľa z localStorage
alebo prázdne pole.
Načítanie záznamov z localStorage
máme, teraz pridáme aj
ich ukladanie pri pridaní nového záznamu. Záznamy budeme ukladať ako do
poľa zaznamy
, tak do storage. Pracovať v celej aplikácii len sa
storage by vyžadovalo neustále prevádzanie záznamov z objektu na text a
späť. Preto ho využívame len pre načítanie na začiatku a priebežné
ukladanie.
Do metódy nastavUdalosti()
pridáme jeden riadok ukladajúce
záznam aj do storage:
nastavUdalosti() { this.potvrditButton.onclick = () => { const zaznam = new Zaznam(this.nazevInput.value, this.datumInput.value); this.zaznamy.push(zaznam); localStorage.setItem("zaznamy", JSON.stringify(this.zaznamy)); // přidaný řádek this.vypisZaznamy(); }; }
Môžeme projekt skúsiť spustiť, pridať úlohy a znova načítať stránku. Úlohy v aplikácii už teraz zostávajú a to znamená, že máte svoju prvú reálne použiteľnú objektovú aplikáciu. Gratulujem! To je pre dnešok všetko, celkom ľahko sme si vyriešili náš problém s ukladaním. V budúcej lekcii, Vylepšenia objektového diáre v JavaScripte , už diár plne dokončíme