NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
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í.

Diskuze – Lekce 9 - OOP diář v JavaScriptu - Formátování a mazání záznamů

Zpět

Upozorňujeme, že diskuze pod našimi online kurzy jsou nemoderované a primárně slouží k získávání zpětné vazby pro budoucí vylepšení kurzů. Pro studenty našich rekvalifikačních kurzů nabízíme možnost přímého kontaktu s lektory a studijním referentem pro osobní konzultace a podporu v rámci jejich studia. Toto je exkluzivní služba, která zajišťuje kvalitní a cílenou pomoc v případě jakýchkoli dotazů nebo projektů.

Komentáře
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Blanka Svobodová
Lubor Pešek:4.8.2022 17:46

Čau, tak ti to jdu sem hodit.
Dal jsem si s tím práci, kód samozřejmě narostl, ale můžeš sama zkusit, jaké to má výhody.

Předně - dobré je začínat z nějakého Managera. V podstatě na tom jsou postavené i frameworky - je někde nějaký manager nebo container, který vše spravuje.
Takto by i kódy měly vypadat (podotýkám, že to tak platí na backendu. Jestli to samé platí i pro FE, na to se musí když tak vyjádřit zkušenější frontendisti).
Takže začnu tou třídou manager (ta i obsahuje provolání window.onload, přijde mi zbytečné to volat v separátním scriptu)

window.onload = function () {
    new Manager();
}

class Manager {

    constructor() {
        this.init();
        this.vypisZpracovaneZaznamyDoVypisu();
    }

    init() {
        this.tool = new Tool();
        this.diar = new Diar(this.tool);
        this.elementy = new Elementy(this.tool, this);
    }

    refreshVypisu(pole) {
        this.elementy.vypisElement.innerHTML = "";
        for (let zaznam of pole) {
            let ukolInfo = document.createElement("p");
            ukolInfo.className = "ukol";
            let datum = document.createElement("h3");
            datum.innerHTML = this.tool.formatData(zaznam.datum);
            ukolInfo.appendChild(datum);
            this.pridejUkoly(zaznam, pole, ukolInfo);
        }
    }

    vypisZpracovaneZaznamyDoVypisu() {
        this.refreshVypisu(this.diar.zaznamy);
    }

    aktualizujASetridDiar() {
        this.diar.nactiZaznamyZLocalStorage();
        this.diar.setridDiar();
    }

    pridejUkoly(zaznam, pole, ukolInfo) {
        for (let ukol of zaznam.ukoly) {
            this.pridejPrvkyUkolu(ukol, zaznam, pole, ukolInfo);
        }
    }

    pridejPrvkyUkolu(ukol, zaznam, pole, ukolInfo) {
        ukolInfo.innerHTML += `<h4>${ukol.nazev}</h4><br>úkol ${ukol.splneno ? "<span class='zelene tucne'>" : "<span class='cervene tucne'>ne"}splněn</span><br>`;
        this.elementy.vypisElement.appendChild(ukolInfo)
        this.pridejTlacitka(ukol, zaznam, pole, ukolInfo);
    }

    pridejTlacitka(ukol, zaznam, pole, ukolInfo) {
        //tlačítko smazat
        this.elementy.vytvorAPridejTlacitko("Smazat", () => {
            if (confirm("Opravdu si přejete odstranit úkol?")) {
                zaznam.ukoly = zaznam.ukoly.filter(z => z !== ukol);
                if (zaznam.ukoly.length === 0) {
                    pole = pole.filter(z => z !== zaznam);
                }
                let jsonZaznamy = this.tool.prevedNaJSON(pole);
                this._ulozZaznamy(jsonZaznamy);
                this.vypisZpracovaneZaznamyDoVypisu();
            }
        }, ukolInfo);

        //tlačítko označit
        this.elementy.vytvorAPridejTlacitko("Označit jako " + (ukol.splneno ? "ne" : "") + "splněn", () => {
            ukol.splneno = !ukol.splneno;
            let jsonZaznamy = this.tool.prevedNaJSON(pole);
            this._ulozZaznamy(jsonZaznamy);
            this.vypisZpracovaneZaznamyDoVypisu();
        }, ukolInfo);
    }

    _ulozZaznamy(jsonZaznamy) {
        this.tool.ulozDoLokalnichZaznamu(jsonZaznamy);
        this.elementy.vypisElement.innerHTML = "";
        this.aktualizujASetridDiar();
    }
}

Když se na to podíváš, tak třída obsahuje 9 metod.
Neděs se toho, je tam i tolik metod už hned na začátku třeba proto, protože jsou některé preventivní, aby se mi v metodách nekupily závorky z cyklů a ifů (lepší než psát několik cyklů do sebe, tak je provolat metodu, která pak vyvolá vnořený cyklus. Trošku líp se to debuguje, ale kód je malinko lépe čitelnější).

Předně počítej s tím, že nebudeš nic nikde vyhledávat. V kódu se orientuješ pomocí odkazů. Stačí podržet CTRL a kliknout na název volané metody a IDE tě tam samo přepne.

Když se tedy podíváš do konstruktoru, tak tam jsou dvě metody. Jedna init (ta bude nejspíš něco inicializovat) a druhá vypisZpracova­neZaznamyDoVy­pisu.
Byl jsem hodný a zachoval jsem tu češtinu, ale věř, že to byla šílená oběť :D
Snad už z toho názvu jde také usoudit, že ta metoda zpracuje záznamy a pak je vypíše do nějakého výpisu.
Ano, dalo by se to řešit i parametricky. Popravdě jsem to tak měl, ale nechtěl jsem zase doopravdy vytvořit 20 metod o jednom řádku. Zase musíme být trošku i rozumní.

Když si přjdeš do metody init (podržíš CTRL a v konstruktoru klikneš na this.init() ), tak ona skutečně nebude dělat nic jiného, než že vytvoří nějaké tři tři třídy.

Tool třída vypadá takto:

class Tool {

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

    prevedZJSON(object) {
        return JSON.parse(object);
    }

    prevedNaJSON(object) {
        return JSON.stringify(object);
    }

    nactiLokalniZaznamy() {
        return localStorage.getItem("zaznamy") !== null ? localStorage.getItem("zaznamy") : "[]";
    }

    ulozDoLokalnichZaznamu(zaznamy) {
        localStorage.setItem("zaznamy", zaznamy);
    }

    formatData(datum) {
        return new Date(datum).toLocaleDateString(this.jazyk, {
            weekday: "long",
            day: "numeric",
            month: "long",
            year: "numeric"
        });
    }

    setridPolePodleDatumu(pole) {
        pole.sort((a, b) => new Date(a.datum) - new Date(b.datum));
    }
}

V téhle třídě skutečně neděláš nic jiného, než že zpracováváš objekt do JSONu a zpátky + ukládáš záznamy (jakékoliv, nejen JSON) do localStorage, případně nastavuješ formát data nebo třídíš pole.
Prostě skutečně nástrojová třída.
Lepší by bylo, kdyby tato třída byla statickou knihovnou, ale přiznám se, nevím, jestli v JS statika vůbec je. Možná se k tomu dostaneme v seriálu :)

Abych nemusel pořád tuto třídu tedy vytvářet, tak jsem vytvořil v init metodě pouze jednu instanci této třídy a předávám ji jako parametr třídám Diar a Elementy.
Elementům ještě předávám i instanci managera, protože tam jsou posluchače (teda jeden posluchač), který potřebuje dát managerovy podnět, aby překreslil výsledky.

Opět ve frameworku by bylo lepší použít autowired notaci, ale teď ani žádný framework nepoužíváme, takže si holt musím poradit takto.

Třída Diar vypadá takto:

class Diar {

    constructor(tool) {
        this.tool = tool;
        this.zaznamy = [];

        this.nactiZaznamyZLocalStorage();
    }

    /**
     * Kdyby tato metoda byla pojmenována pouze nactiZaznamy, tak by pak nebylo moc logické, proč tu parsuje nějaký JSON
     * Ono když se takto přemýšlí i nad tou logikou, tak pak to pomáhá trošku i k pojmenování metod
     */
    nactiZaznamyZLocalStorage() {
        let JSONzaznamy = this.tool.nactiLokalniZaznamy();
        this.zaznamy = this.tool.prevedZJSON(JSONzaznamy);
    }

    setridDiar() {
        this.tool.setridPolePodleDatumu(this.zaznamy);
    }
}

Ta opravdu jako správné DTO (Data Transfer Object) zpracovává pouze a jenom záznamy + metoda k jejich třízení.
No a přišlo mi rozumné, že si diář dokáže načíst sám do sebe (do svých záznamů) položky z localStorage. Diáři jako takovému nebude nikdo nic zapisovat. On si to vždycky zapíše sám (pomocí metody nactiZaznamyZ­LocalStorage() ).
Takže je to dynamické a pokud budeš chtít něco uložit do diáře, tak to uložíš do localStorage a pak provoláš jen tuto metodu a Diář si to sám načte.
V případě, že bys chtěl použít jiný načítací zdroj, tak to změníš pouze tady na jednom místě (+ všude tam, odkud se bude do diáře ukládat).

Nejlépe by se to celkově řešilo přes nějakou další třídu, která by zdroj ukládání měla přímo na starost. A diář, který by z aktuálního zdroje četl + jiní posluchači, kteří by do toho zdroje ukládali, tak by se vždy odkazovali na nějakou konfigurační třídu)

No a na práci s tím ukládáním DIář používá třídu Tool. Je mu jedno, jak si to ta třída zařídí - on si to prostě chce uložit a o víc se nestará. O to, ať se stará třída Tool.

Vrátíme se zpátky k třídě Manager do metody init. Je tu poslední třída - Elementy, které předám zase tool + toho managera.
Ve třídě elementy nebudeme řešit nikdy nic jiného, než práci s komponentami, které se budou zobrazovat. Jejich vytváření, načítání a používání. Klidně by tam mohlo být i jejich modifikování (úprava textu atd.). Takže pro tebe jako pro programátorku je to velice jednoduché. Když bys měla někdy task, že budeš muset přidat/odebrat nebo vytvořit nové chování nějakého elementu, tak to budeš hledat pouze v téhle třídě.

Třída Elementy:

class Elementy {

    constructor(tool, manager) {
        this.nazevInput = document.getElementById("nazev");
        this.datumInput = document.getElementById("datum");
        this.potvrditButton = document.getElementById("potvrdit");
        this.vypisElement = document.getElementById("seznam-ukolu");

        this.tool = tool;
        this.manager = manager;
        this.nastavUdalosti();
    }

    nastavUdalosti() {
        this.potvrditButton.onclick = () => {
            let zaznam = this.vytvorNovyZaznamZInputu();
            this.pridejZaznamDoLokalnichZaznamu(zaznam);
            this.manager.aktualizujASetridDiar();
            this.manager.vypisZpracovaneZaznamyDoVypisu();
        }
    }

    vytvorNovyZaznamZInputu() {
        let datum = this.datumInput.value;
        let nazev = this.nazevInput.value;
        return new Zaznam(datum, [new Ukol(nazev, false)]);
    }

    /**
     * Toto je čistě logická metoda. Takováto logika (co se týče ukládání) by za normálních okolností určitě byla na BE
     *
     * U této metody musíme usuzovat, že přidat záznam do lokálních záznamů znamená:
     * 1. načíst lokální záznamy
     * 2. zpracovat je do použitelného pole (vyparsovat z JSON objektu)
     * 3. PŘIDAT ZÁZNAM (s mapou by to bylo lehčí)
     * 4. převést pole zpátky do JSON
     * 5. uložit záznam
     *
     * @param zaznam
     */
    pridejZaznamDoLokalnichZaznamu(zaznam) {
        let jsonZaznamy = this.tool.nactiLokalniZaznamy();
        let zaznamy = this.tool.prevedZJSON(jsonZaznamy);
        this._vlozNovyZaznamPokudNeexistuje(zaznamy, zaznam); //tohle by nahradila mapa, která v Javě má metodu putIfAbsent. V JS nevím, jestli něco takového je
        jsonZaznamy = this.tool.prevedNaJSON(zaznamy);
        this.tool.ulozDoLokalnichZaznamu(jsonZaznamy);
    }

    /**
     * Tato metoda projde záznamy. Pokud záznam již existuje (existuje datum v seznamu), tak přidá k tomuto datu úkol.
     * Pokud neexistuje, tak celý záznam přidá do pole
     *
     * PS: a současně tu máme i připravenou v podstatě logiku, kdybychom najednou někdy v budoucnu rozšířili aplikaci
     * a chtěli i přidávat víc úkolů pro jeden den :)
     *
     * @param zaznamy
     * @param novyZaznam
     * @private
     */
    _vlozNovyZaznamPokudNeexistuje(zaznamy, novyZaznam) {
        for (let zaznam of zaznamy) {
            if (zaznam.datum === novyZaznam.datum) {
                zaznam.ukoly.push(novyZaznam.ukoly[0]);
                return;
            }
        }
        zaznamy.push(novyZaznam);
    }

    vytvorAPridejTlacitko(titulek, callback, element) {
        const button = document.createElement("button");
        button.onclick = callback;
        button.innerText = titulek;
        element.appendChild(button);
    }
}

Pak jsou tu ještě dvě poslední třídy, které souvisí s tím Diářem. Obě jsou opět jen DTO (DTO, neboli Data Transfer Object je obyčejná třída, která pouze a jenom představuje třídu, kde jsou jeji atributy, které do sebe ukládá a které vrací. Žádnou logiku by moc v sobě neměla obsahovat. Maximálně nějaou úpravu těch atributů (jako třeba v tom diáři třízení), ale ani to není úplně čisté.
No a přiznám se, že by neměla obsahovat ani to načítání, ale z lenosti jsem to tam teď hodil :D
Pořád je to menší prohřešek, než to cpát všechno do jedné metody.

Takže takto vypadají:
Třída Záznam:

class Zaznam {

    constructor(datum, ukoly) {
        this.datum = datum;
        this.ukoly = ukoly;
    }
}

a třída Úkol:

class Ukol {

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

Jsou skutečně jednoduché.

No a hlavní logika tedy celkově spočívá ve třídě Manager.
Další část logiky je ještě ve třídě Elementy, protože ta obsahuje posluchače pro komponenty.
Klidně bych mohl funkci těchto posluchačů hodit také do třídy manager, ale posluchač by měl být u té dané komponenty. Toto je diskutabilní a záleží fakt na architektuře programátora. Já to zvolil takto.

No a tím je celé roztřízení hotovo.
Teď se můžeš jen podívat a projít si postupně ty metody.
Není tam nic ale fakt vůbec nic jiného, než co je v těhle tutoriálech.
CSSko je stejné, jako tady na konci ukázky a to samé i index html:

<!DOCTYPE html>
<html lang="cs-cz">
<head>
    <meta charset="UTF-8">
    <title>Diář</title>
    <script src="js/diar.js"></script>
    <script src="js/tool.js"></script>
    <script src="js/ukol.js"></script>
    <script src="js/elementy.js"></script>
    <script src="js/zaznam.js"></script>
    <script src="js/manager.js"></script>
    <link rel="stylesheet" href="css/styly.css" type="text/css">
</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>
</body>
</html>

Akorát jsem si to cssko hodil separátně do jiného filu:

* {
    font-family: Segoe UI Light, "Calibri Light", sans-serif;
}

button {
    padding: 10px 16px;
    font-weight: 600;
    background: #2792e0;
    color: #fff;
    border: none;
    cursor: pointer;
    transition: 1s;
}

button:hover {
    background: #2954c2;
}

button:active {
    background: #5a2099;
}

input {
    min-width: 250px;
    padding: 8px;
    border: 1px solid #909090;
    height: 20px;
}

button, input {
    margin-top: 1rem;
    outline: none;
}

.ukol {
    width: 75%;
    padding: 2rem;
    margin: 1rem auto;
    border: 1px solid #c5c5c5;
    box-shadow: 2px 2px 4px #b1b1b1;
}

.zelene {
    color: green;
}

.cervene {
    color: red;
}

.tucne {
    font-weight: bold;
}

Jo a změnil jsem si barvičku u aktivace tlačítka + transition jsem zvýšil na sekundu :D to je celá velká změna v css :D:D

Každopádně když si projdeme ty dvě třídy (Elementy a Manager), tak jaké tam jsou metody:
Elementy:

  • V konstruktoru je to jasné - nastaví se základní elementy (vytáhnou se z HTMLka ty elementy, které budeme používat)
  • metoda nastav udalosti je stejná, jako v ukázce. Ta prostě jen přidá všem (v tomto konkrétním případě jednomu) elementům posluchače. Konkrétně tlačítku.

Ale jak vidíš, tak tam také není žádná implementace, ale provolávání metod.
Takže když se klikne na tlačítko tak se:

  1. vytvoří nový záznam z inputů (metoda je tak pojmenovaná a nic jiného, než že to vytáhne data z jiných inputů a vytvoří to jeden objekt, neudělá). Takže opět pro tebe je to info, že kdybys tam přidala tlačítko, které nastaví každému úkolu třeba barvičku, tak to určitě budeš potom přidávat na tomto místě
  2. přidej záznam do Lokálních záznamů (tam je i JavaDoc, neboli komentář, ve kterém to popisuju. Nepojmenoval jsem to záměrně ulozData, ale přidej k záznamům. Pak si můžu dovolit, že nejdřív v takové metodě musím získat zdroj, klidně si ho upravím, pak to do něj přidám a až pak to uložím
  3. aktualizuj a setřid diař. Tak od této metody bych očekával, že si natáhne aktuální data a následně je setřídí. No a když si do té metody přejdeš tak zjistíš, že to tak je (vykonává to manager).

Určitě bys v takové metodě asi nečekala, že ti vytvoří kočárek a pochová dítě. Nebo že ti bude formátovat čas

  1. no a když to mám všechno nachystané, tak jen vypíšu zpracované záznamy. Uznávám, že toto bych tady mohl klidně přejmenovat (ale už se mi nechtělo :D) tak, jak to pak volám v té metodě - že pro mě výpis znamená, že přepíšu ty stávající záznamy (a to znamená, že smažu výpis a nahraju to tam znova).

No a to také není úplně jednoznačně vypovídající. Mohl jsem toto pojmenovat líp. Od výpisu by málo kdo čekal refresh.

  • Pak je tu ještě metoda _vlozNovyZaznam­PokudNeexistu­je. Tu jsem tam popsal, tak nemusím už opakovat, co je jednou napsáno
  • no a metoda vytvorAPridej­Tlacitko(?,?,?) asi bude vytvářet a přidávat k nějakému elementu tlačítka. No a kde jinde by měla taková metoda být, než ve třídě, která má elementy na starost?:)

No a ve třídě Manager máme ještě metody:
refreshVypisu
Tato metoda ke konci používá metodu pridejUkoly
která proiteruje všechny úkoly, které záznam obsahuje a pak s nimi pracuje pomocí metody pridejPrvkyUkolu a v této metodě ještě na konci provolávám metodu pridejTlacitka

No a každá metoda tedy vykonává to, podle čeho je pojmenována.

Určitě by se i tento můj výtvor dal po této stránce vylepšit.
On nic neurychluje ani nijak jinak neimplementuje. Vše, co bylo v tomto seriálu, tak je akorát jinak zapsáno.
Ovšem když ti následně potom třeba v konzole přijde tato hláška:

**Uncaught TypeError: pole is not iterable
    at Manager.refreshVypisu (manager.js:20:28)
    at Manager.vypisZpracovaneZaznamyDoVypisu (manager.js:31:14)
    at new Manager (manager.js:9:14)
    at window.onload (manager.js:2:5)**

Tak uznej sama, že se to daleko lépe debuguje.
Podíváš se do třídy Manager na řádek 20.
Zjistíš, že pole nemůže proiterovat. Řekneš si a proč?
Tak si tam na ten řádek hodíš brakepoint a zjistíš, že pole je undefined.
Tak se podíváš, kde jej bereš - aha z parametru.
Tak kdo tuhle metodu volá? řádek 31 ve stejné třídě.
Tak se na to podíváš a zjistíš, že jako parametr předáváš ne this.diar.zaznam, ale this.diar.zazna (žes třeba omylem smazala to M na konci).

Samozřejmě takhle jde i poznat chyba v ukázkovém příkladě. Také to jde takhle debugovat.
Ale čím víc logických prvků (tříd a metod) máš, tak se ti lépe pak v tom kódu orientuje.

Nehledě na to, že kdybych ti třeba teď zadal úkol, abys přidala input a každý úkol bude mít třeba index závažnosti, tak už se v tom budeš mnohem rychleji orientovat.

Když máš dva vnořené cykly a metodu na 100 řádků a musíš v jedné metodě scrollovat, tak pak se v tom i tvá orientace velmi rychle ztrácí.
Nevím teď přesně kolik (dá se to vygooglit), ale metoda by měla mít tuším že max 50 řádků. Pokud se nejedná o nějaký složitý výpočet umělé inteligence :D

Tak, myslím, že je to hodně vyčerpávající a pokud něco pochytíš, bude jen dobře.
Kdybys měla jakékoliv otázky, neboj se zeptat. Kdo se ptá - naučí se, kdo se neptá a brečí, tak je ztracený.

Odpovědět
4.8.2022 17:46
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:4.8.2022 17:46

kua, zase komentář delší jak článek -.-

Odpovědět
4.8.2022 17:46
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
Odpovídá na Lubor Pešek
Blanka Svobodová:5.8.2022 22:01

tak tomu říkám hustá odpověď!!!!! To si snad zarámuju! Megadík

Odpovědět
5.8.2022 22:01
Kdy, když né teď. Kdo, když né já?
Avatar
Michal D.
Tvůrce
Avatar
Michal D.:16.8.2022 17:24

ve vysvětlivkách použito nesprávně toLocaleString(), správně toLocaleDateString()

 
Odpovědět
16.8.2022 17:24
Avatar
Petr Zabransky:9.1.2023 21:41

Podle mě principem OOP je vytvářet objekty jako je třeba tento diář jako samostatné znovu použitelné komponenty. Tak abychom mohli použít treba 3 nezávislé diáře na jedné stránce a nemuseli psát kód 3x. Pak ale nemůžeme odkazovat na konkrétní inputy v HTML, ale musí si je každá instance diáře buď vytvořit sama nebo u každého diáře určíme jeho jedinečné ID v HTML a jeho elementy jako butony a inputy pak označime stejnou třídou ve vsech instancich a přistupovat k nim budeme pomocí ID diáře.

 
Odpovědět
9.1.2023 21:41
Avatar
Petr Zabransky:11.1.2023 11:57

Každý záznam by měl mít jednoznačné ID a podle něj k němu přistupovat. I u toho mazání. Takhle to je podle mě z principu špatně. Navíc u toho filtrování takhle nevíme co nastane, když třeba budeme mít dva stejné záznamy v jeden den, což je úplně běžné a budeme chtít vymazat jen jeden. Tohle jsou přece úplné základy práce s objekty. Stejně jako v mém předchozím přízpěvku o "nezávislých komponentách". Doporučoval bych více se zaměřit v každé lekci na její podstatu a méně na nepodstatné ladění detailů, které stejně příklady akorát znepřehledňují. Všiml jsem si už víckrát, že tohle je tady takový obecný nešvar.

 
Odpovědět
11.1.2023 11:57
Avatar
Odpovídá na Lubor Pešek
Petr Zabransky:18.2.2023 21:05

Taky děkuju za vyčerpávající vysvětlení. Líbí se mi ten systém Manageru jako správce. Neměl bys prosim tě nějaký tip, jak spravovat kód na webu, kde je více stránek a více stejných komponent udělaných jako objekty ? Systém, jak zaregistrovat všechny komponenty a aby se v tom člověk vyznal i po čase. Děkuji.

 
Odpovědět
18.2.2023 21:05
Avatar
Lubor Pešek
Člen
Avatar
Odpovídá na Petr Zabransky
Lubor Pešek:19.2.2023 0:13

V podstatě z logiky, se kterou se běžně setkávám, tak ty takové věci nemusíš řešit.
Proč bys měl někde centrálně evidovat informace o naprosto všech komponentech použitých na X stránkách?
Pokud jde o stylování - proto je to vytvářené z nějaké šablony či přímo třídy (a její definici pak lehce změníš - pak všechny objekty změní svůj design či nějaké specifické chování).

Ale proč by manager měl evidovat tyhle objekty? To pak naprosto ztrácí smysl celého OOP.
Důležité je, že se k těm objektům dokážeš dostat. Přes nějakou vlastní správu je potřeba evidovat tu hlavní komponentu (v tomto případě třeba linky na jednotlivé stránky). No a ta samotná stránka už pracuje s tou komponentou tak, jak potřebuje.

Možná správně nechápu ten požadavek, ale principem OOP je právě to, abys nemusel mít na jednom místě úplně všechny informace, ale abys měl nějakou hlavní řídící jednotku, která následně s ostatními komponenty komunikuje. A navíc tyto komponenty dokáží komunikovat nezávisle na druhých i s druhými (zní to zmatečně, ale v konečném důsledku by to tak mělo být - neměl bys být závislý na dalších komponentech, ale když potřebuješ, měl bys mít možnost se k nim dostat).

V podstatě na tom samém principu funguje i celý Spring. Máš nějaký aplikační server a co ten potřebuje úplně v základu? Soubor web.xml, ve kterém máš ty nejzákladnější údaje (servlet, mapování na danou url a třídu, která bude úplně základním controllerem, kterým se spustí prvotní akce).
No a z toho se to všechno odvíjí. To, že potom jednoduše skáčeme na různé stránky pomocí requestů, tak to je další usnadnění.
Ale v samotném základu můžeš ten web.xml považovat také za takového managera, ze kterého se to pak všechno odvíjí.

Odpovědět
19.2.2023 0:13
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
Odpovídá na Petr Zabransky
Lubor Pešek:19.2.2023 0:16

Když mi položíš takovouto otázku (abych neuhnul od tématu), tak se přiznám, že mě prvně napadá proti otázka - proč je potřeba znát právě ty komponenty, které si už přizpůsobuje každá jednotlivá stránka?
Ty komponenty budou vždy už jedinečnými objekty (budou používat různý model atd.)
Jejich stylování a případná změna, tak ta je zajištěna stylováním (v případě kupříkladu Javy by to řešil také nějaký konfigurák dané třídy, kde bys nastavoval opět styly).

Ale nevím všechno (proto se rád do takových diskuzí zapojuji) a rád se nechám poučit. Tak mi dej příklad, kdy je potřeba si ty komponenty evidovat a zkusím popřemýšlet. Já se popravdě s takovým problémem nikdy nesetkal.

Odpovědět
19.2.2023 0:16
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
Odpovídá na Lubor Pešek
Petr Zabransky:19.2.2023 12:11

Děkuji za odpověď. Upřesním ten můj požadavek.

  1. Dělám webovou aplikaci a nechci použít framework jako třeba React, který to samozřejmě řeší. Mám rád jednoduchost a základní technologie.
  2. Mám na stránce různé komponenty. Třeba rozbalovací "read more" s nějakou akcí, buttony, inputy na které reagují jiné elementy atd. a pak nějaké složitější objekty s vykreslováním na canvas.
  3. Každou komponentu mám zvlášt v modulu.
  4. Pak ale potřebuju nějaký hlavní skript (Manager), který je při spuštění aplikace nebo načtení stránky všechny načte (aktivuje)
  5. Některé složitější komponenty budou OOP a některé budou mít jen jednoduchou funkci.
  6. Ty jednoduché budou mít v sobě třeba projetí cyklem všechny elementy s třídou třeba "btn" a nastevní jim nějaké eventy. Ty složitější si pomocí toho Manageru vytvoří instance atd.
  7. Při větším počtu komponent se v tom podle mě takhle ztratím. Proto hledám řešení, jak se to řeší profesionálně. Jestli je nějak aktivovat centrálně nebo jak.
  8. Abych byl úplně konkrétní, tak něco takového začínám řešit třeba na "":www.fraktaly.cz

Pokud se chceš podívat na kód, tak "":https://github.com/…sky/fraktaly

 
Odpovědět
19.2.2023 12:11
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 34.