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í.

Diskusia – 9. diel - OOP diár v JavaScripte - Formátovanie a mazanie záznamov

Späť

Upozorňujeme, že diskusie pod našimi online kurzami sú nemoderované a primárne slúžia na získavanie spätnej väzby pre budúce vylepšenie kurzov. Pre študentov našich rekvalifikačných kurzov ponúkame možnosť priameho kontaktu s lektormi a študijným referentom pre osobné konzultácie a podporu v rámci ich štúdia. Toto je exkluzívna služba, ktorá zaisťuje kvalitnú a cielenú pomoc v prípade akýchkoľvek otázok alebo projektov.

Komentáre
Avatar
prokop.mejstrik:2.4.2021 23:39

Ahoj, pokud někdo narazil na problém, že tlačítka na mazání záznamů nefungují, tak je to z důvodu, že změna vlastnosti .innerHTML při překreslování ruší eventListenery na podobjektech. (Alespoň tak jsem to jako začátečník pochopil. :D )
Řešením je použití .insertAdjacen­tHTML(position, text) - více na MDN nebo pomocí JQuery metody .append().

Ani v přiloženém zdrojovém souboru mi to nefungovalo správně, a opozornil bych že soubor pod touto lekcí neodpovídá lekci :) (chybí tam ty tlačítka na to mazání).

Je to ale skvělý tutoriál, díky moc!

Editované 2.4.2021 23:39
 
Odpovedať
2.4.2021 23:39
Avatar
Vojtěch Perník:14.6.2021 19:10

Chtělo by to v upoutávce na tuto lekci přepsat {PREVIOUS} na {NEXT}. Takhle se u předchozí lekce zobrazuje v upoutávce odkaz ještě na lekci předchozí.

V příští lekci, Formát JSON, do našeho objektového diáře v JavaScriptu přidáme několik dalších funkcí.

 
Odpovedať
14.6.2021 19:10
Avatar
Odpovedá na prokop.mejstrik
Václav Švarc:3.9.2021 17:39

Díky za tento postřeh, docela jsem se trápil jestli to není zase nějaká bezpečností kulišárna ze strany Chromu.

Vyřešil jsem nakonec právě použitím

element.insertAdjacentHTML("beforeend", text)

Stálo by za to upozornit na tuto okolnost i v článku.

 
Odpovedať
3.9.2021 17:39
Avatar
Šimon Raichl
Tvůrce
Avatar
Odpovedá na prokop.mejstrik
Šimon Raichl:18.11.2021 0:01

Ahoj, neni to primo tak, ze pomoci innerHTML zrusis vsechny listenery ze vsech elementu, ve skutecnosti se prepisi vsechny puvodni elementy za nove, ktere uz nemaji zadne event listenery nastavene, ale z praktickeho hlediska je vysledek presne takovy, jaky jsi napsal.

 
Odpovedať
18.11.2021 0:01
Avatar
Jaroslav Drobek:22.6.2022 5:49

Hodnocení:

  • "...použijeme její metodu toLocaleDateS­tring(),"
  • Kód odstraňující položku: "bohužel" jen pro nematematiky - až na drobnou odlišnost syntaxe používá metoda filter zápis množiny pomocí vlastnosti..je to docela sympatické 👍
 
Odpovedať
22.6.2022 5:49
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:2.7.2022 21:01

Viz komentář (popis funkcí ok, ale obecně se zde porušuje zásadní pravidlo OOP a naučíte nováčky velmi hnusný návyk!)

Odpovedať
2.7.2022 21:01
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:2.7.2022 21:14

Zdravíčko,

s touto lekcí začínám mít zásadní problém a měli byste se nad tím velmi rychle zamyslet, než vychováte nevědomky programátory nemehla.
Bohužel se s tím setkávám i v praxi (v Javě), kdy se právě nováčci učí na takových tutoriálech.

Nemám nic proti funkcím, které se tu probírají. Tento seriál je i v pořádku, co se týče přehlednosti a vysvětlování.

Problém ovšem je, že pokud je to seriál o OOP, tak by se zde měly i základní myšlenky OOP dodržovat.
Nezlobte se na mě, ale OOP vychází především z faktu, že chce virtuální svět a programování přiblížit co nejvíce reálnému světu.
No a teď si vezměte tu metodu vypisZaznamy()

V rámci čitelnosti kódu. Co byste asi tak čekali, když byste někde viděli v seznamu možností .vypisiZaznamy()??
Pochybuji, že byste v takové metodě očekávali definici stylování datumu, vytváření nějakého tlačítka, atd.

Ano, funguje to a přece by bylo hodně zbytečné v triviálním programu vytvářet metodu pro 2 řádky a pak ji volat.

Jenže v praxi se pak stane, že učíte nováčky neoddělovat správně logiku programu.
Začíná to tím, že pak třeba vidím definici metody na 100 řádků. Metoda se jmenuje loadData a já v ní najdu kromě SQL dotazu definici parsování, formátu, mapování, if, který maže nějakou část databáze atd. atd. atd.

No a končí to tím, že pak v business logice vidím entity, části JPA kódu atd.

Prostě toto se mi z hlediska OOP vážně nelíbí. To, že něco funguje, tak je sice hezké, ale metody jsou od toho (a proto se kódy snad člení na jednotlivé metody), aby každá metoda vykonávala takovou funkci, pro kterou je určená.

Také byste v reálném životě nečekali, že funkčnost nastavování barvy ruky najdete v metodě ohniRuku(). Je to absurdita, ale toto se tady takhle ty lidi učí.
Prostě ok, ať ta metoda vypisZaznamy() třeba ty ostatní metody volá, ale ať v ní nejsou proboha ty definice!!!

Mimo jiné docílíte toho, že vám kód nebude odsunovat těla podmínek a cyklů mimo obrazovku.
I to už jsem viděl, že vnitřní logika metody byla tak rozvětvená a zanořená, že když jsem autoformátoval kód, tak mi skutečně kód odjel mimo screen a já viděl cca 20 otevíracích závorek.

Prosím, přepracujte tuhle lekci a klidně kód rozšiřte, ale rozložte definici logických částí do jednotlivých metod.
Je to triviální kód a lidi se to teprve učí, ano, ale právě je učíte nechutný zlozvyk a myslím si, že i když každou tu logiku uvidí samostatně, tak to budou i lépe chápat.

Jinak co se týče úkolu, funkcionalit a vysvětlování, tak za mě bezva práce.

Odpovedať
2.7.2022 21:14
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
Odpovedá na Lubor Pešek
Blanka Svobodová:3.8.2022 23:11

A ukázal bys prosím názorně, jak to elegantněji rozsekat? Já si to jako zelenáč neumím předělat zatím sama...respektive nefunguje mi to pak....díky předem.

Odpovedať
3.8.2022 23:11
Kdy, když né teď. Kdo, když né já?
Avatar
Blanka Svobodová:3.8.2022 23:15

Musela jsem si opravit dosavadní poktok kodu dle přiloženého souboru, v nastavUdalosti nekam zmizel puvodne pridany radek
localStorage.se­tItem("zaznamy", JSON.stringify(this­.zaznamy)); // přidaný řádek.
Proč?

Odpovedať
3.8.2022 23:15
Kdy, když né teď. Kdo, když né já?
Avatar
Lubor Pešek
Člen
Avatar
Odpovedá na Blanka Svobodová
Lubor Pešek:4.8.2022 8:26

Věřím, že bys to zvládla i sama, ale nemám s tím problém.
Tak máš tu tuhle metodu:

vypisZaznamy() {
    this.seradZaznamy();
    this.vypisElement.innerHTML = "";
    let posledniDatum = null;
    for (const zaznam of this.zaznamy) {
        if (zaznam.datum !== posledniDatum) {
            const datum = new Date(zaznam.datum).toLocaleDateString(this.jazyk, {
                weekday: "long",
                day: "numeric",
                month: "short",
                year: "numeric"
            });
            this.vypisElement.insertAdjacentHTML("beforeend", `<h3>${datum}</h3>`);
        }
        posledniDatum = zaznam.datum;

        this.vypisElement.insertAdjacentHTML("beforeend", `<strong>${zaznam.nazev}</strong>
        <br>úkol ${!zaznam.splneno ? "ne" : ""}splněn`);
        const smazatButton = document.createElement("button");
        smazatButton.onclick = () => {
            if (confirm("Opravdu si přejete odstranit úkol?")) {
                this.zaznamy = this.zaznamy.filter(z => z !== zaznam); // Ponechá vše co není rovné proměnné zaznam
                this.ulozZaznamy();
                this.vypisZaznamy();
            }
        };
        smazatButton.innerText = "Smazat záznam";
        this.vypisElement.appendChild(smazatButton);
        this.vypisElement.insertAdjacentHTML("beforeend", "<br>");
    }
}

Základní myšlenka OOP je o tom, že by se měl virtuální svět co nejvíce podobat tomu skutečnému a každý objekt takhle programovat.
Takovým typickým příkladem je programování židle a podlahy. Ty musíš programovat židli tak, aby měla kromě svých atributů a funkcí i kontrolu (validaci), že když ji na nějakou plochu položíš, že se nepropadne "pod zem".
To samé i podlaha - ať na ní položíš cokoliv, ona to nesmí propustit.
V podstatě by stačilo takovou funkcionalitu naprogramovat jen jednomu předmětu (třeba podlaze) a tím bys docílila kýženého výsledku. Jenže ty se musíš na každou funkci dívat tak, aby byla v ideálním případě použitelná i v jiném projektu.
A tak to máš i v praxi. Ty když bys třeba vytvářela papír, tak jej nebudeš vytvářet pouze pro sešit (takže bys mu dala hned linky), ale vytvoříš prázdný papír a ten, kdo bude vytvářet sešit, tak jej potom následně a patřičně upraví podle toho, jak potřebuje.

No a teď si vem tuhle metodu - vypisZaznamy. Když ti řeknu, že existuje funkce vypsání záznamů, tak co bys od takové funkce očekávala? No nejspíš to, že odněkud vezme zdroj (ideálně z parametru, aby to bylo obecné) a někam to vypíše (ok, aby to bylo co nejvíc univerzálnější, tak bys mohla jako druhý parametr nastavit output, kam se to má vypisovat.

Rozhodně bys neočekávala, že tato metoda bude něco řadit, něco stylovat či že bude vytvářet tlačítka.
Teď si vem, že bys tuhle metodu zavolala třeba v aplikaci, která bude počítat goniometrické funkce.
No a najednou zjistíš, že budeš mít k dispozici posluchač pro tlačítko...(res­pektive ty zavoláš metodu vypisZaznamy() a dostaneš chybovou hlášku, že nemůže najít tlačítko smaž.. :) ) asi bys na to koukala jak půl prdele z křoví.

To, o čem mluvím, tak sice na první pohled "zbytečně" navýší kód, ale takhle by se mělo programovat (objektově).
Takže bych tuhle metodu osekal tak, aby skutečně POUZE vypisovala.

vypisZaznamy(output){
    this.vypisElement.innerHTML = "";
    this.vypisElement.insertAdjacentHTML("beforeend", output);
}

Samozřejmě tím najednou všechno chybí a je potřeba to postupně někde dopsat a provolat :)
Takže je tu nějaký průchod tou aplikací. Schválně pojďme si vypsat, co všechno ta metoda děá:

  • promaže output
  • v celém bloku bude třídit záznamy podle data
  • vypíše unikátní datum
  • vypíše názvy k příslušnému datu
  • zjišťuje, zda-li byl úkol splněn nebo ne a následně jej vypíše
  • vytváří nové tlačítko
  • tlaítku nastavuje posluchače
  • implementuje logiku tlačítka
  • nastavuje tlačítko
  • vypisuje tlačítko (ok, technicky to znamená, že přidá tlačítko do elementu)

trošku dost drsné a tohle bych určitě jen tak od takového názvu metody nepředpokládal.
Určitě by nejideálnější řešením mohlo být, že by každý záznam byl skutečně objekt, který bys vytvářela a nastavovala jeho atributy. Klidně by ten objekt mohl obsahovat i to tlačítko (i když i to je věc zobrazování, ale furt by to bylo lepší, než tohle).
Dejme tomu tedy, že bychom měli objekt, Zaznam, který obsahuje atributy: datum, pole objektů úkol (úkol by měl dva atributy - název a jestli byl nebo nebyl splněn).
V rámci tohoto úkolu to tu tuším tak i je (teď si to úplně nevybavím dopodrobna, dělal jsem to před časem), ale o to víc je to smutné, že vše je připraveno a následně se s těmi objekty nepracuje.

V hlavním běhu bys evidovala někde tyto objekty (třeba v nějakém poli). Takže si můžeš vytvořit i funkci, která ti takové pole bude třídit (podle data jednotlivých objektů).
U každého objektu bys řešila tedy evidenci jeho úkolů (vždy, když by se přidával nový úkol, tak by se nejdřív prošlo pole objektů a zjistilo by se, jestli takové datum už neexistuje a pokud ano, tak se jednoduše tento úkol k takovému objektu přidá. Tohle je mimochodem práce s tzv. mapou, která tady ještě zmíněna nebyla, ale přesně tohle by krásně řešila mapa.

A nemusela bys pak v třízení řešit logiku, komu se co má přiřadit a už vůbec ne ve výpisu, kde bys takovou logiku neočekávala.

Takže když to všechno shrnu, tak bys prostě vyházela veškerou logiku z této funkce (vyházela, ne smazala) a použila ji před tím a trošku jinak a pro každou jednotlivou logiku vytvářela funkce, které bys potom postupně volala.

Výsledek se nesmí nijak změnit, kód ti sice naroste, ale důležitá myšlenka hlavně tkví v tom, že když bys za čas chtěla kód upravit, tak se budeš v něm lépe orientovat. Nehledě na to, že se lépe píšou unitové testy.
ANO, může dojít k tomu, že pak budeš v uvozovkách kvůli blbému výpisu vytvářet separátní metodu, takže místo 1 řádků napíšeš tři řádky.

Teď ti prozradím něco z praxe. Je jedno, pokud má soubor třeba 10 000 řádků, pokud máš kód rozdělen do logických celků (metod, funkcí a tříd). NIKDY si v praxi neprocházíš kód tak, že si otevřeš soubor a čteš si ho od shora dolů. To je strukturované programování. V objektově orientovaném programování si vždy čteš metodu, kterou chceš řešit. Pak je už důležité, aby taková metoda byla co nejstručnější.
Věř, že lépe budeš upravovat metodu, která bude řešit třeba jen formátování textu, než metoda, která bude mít v sobě formátování textu, výpis, přidání tlačítka, parsování data, načítání JSONu atd. atd. atd.
V praxi to doopravdy probíhá tak, že když debuguješ kód, tak jdeš po jednotlivých metodách. Pokud metodu jednoznačně nepochopíš do 2 sekund (i se čtením názvu), tak je špatně navržená.

To je i to, proč jsem ten komentář psal. Už je mi smutno, když třeba v práci otevřu metodu, která má ukládat data do databáze a první co v ní najdu, tak select, který mi nejdřív tahá data od jinud, abych část dat doplnil do textu, který chci uložit. Prostě když mám metodu ulož do databáze, tak ta metoda má skutečně jen použít již nastavenou sessionu a provolat metodu, která uloží text z parametru do databáze. Nic víc od toho nemůžu očekávat.

Po práci napíšu kód, jak bych si to konkrétně třeba já představoval. Není to úzus, určitě by se našlo i lepší řešení (vždycky existuje lepší řešení), ale bude to řešit problém, který já v tomhle vidím.

Odpovedať
4.8.2022 8:26
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!