15 KiB
Vytvoření bankovní aplikace, část 1: HTML šablony a trasy ve webové aplikaci
Kvíz před lekcí
Úvod
Od vzniku JavaScriptu v prohlížečích se webové stránky stávají interaktivnějšími a složitějšími než kdy dříve. Webové technologie se nyní běžně používají k vytváření plně funkčních aplikací, které běží přímo v prohlížeči, a nazýváme je webové aplikace. Protože jsou webové aplikace vysoce interaktivní, uživatelé nechtějí čekat na úplné načtení stránky pokaždé, když provedou nějakou akci. Proto se používá JavaScript k přímé aktualizaci HTML pomocí DOM, aby se zajistil plynulejší uživatelský zážitek.
V této lekci položíme základy pro vytvoření bankovní webové aplikace, přičemž použijeme HTML šablony k vytvoření více obrazovek, které lze zobrazit a aktualizovat bez nutnosti znovu načítat celou HTML stránku.
Předpoklady
Pro testování webové aplikace, kterou v této lekci vytvoříme, potřebujete lokální webový server. Pokud ho nemáte, můžete si nainstalovat Node.js a použít příkaz npx lite-server
ve složce svého projektu. Tím vytvoříte lokální webový server a otevřete svou aplikaci v prohlížeči.
Příprava
Na svém počítači vytvořte složku nazvanou bank
a uvnitř ní soubor index.html
. Začneme s tímto HTML základem:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bank App</title>
</head>
<body>
<!-- This is where you'll work -->
</body>
</html>
HTML šablony
Pokud chcete vytvořit více obrazovek pro webovou stránku, jedním řešením by bylo vytvořit jeden HTML soubor pro každou obrazovku, kterou chcete zobrazit. Toto řešení však přináší určité nevýhody:
- Při přepínání obrazovek musíte znovu načíst celé HTML, což může být pomalé.
- Je obtížné sdílet data mezi různými obrazovkami.
Dalším přístupem je mít pouze jeden HTML soubor a definovat více HTML šablon pomocí elementu <template>
. Šablona je znovupoužitelný HTML blok, který není prohlížečem zobrazen a musí být instancován za běhu pomocí JavaScriptu.
Úkol
Vytvoříme bankovní aplikaci se dvěma obrazovkami: přihlašovací stránkou a dashboardem. Nejprve přidáme do těla HTML prvek zástupce, který použijeme k instancování různých obrazovek naší aplikace:
<div id="app">Loading...</div>
Dáváme mu atribut id
, aby bylo později snazší ho najít pomocí JavaScriptu.
Tip: protože obsah tohoto prvku bude nahrazen, můžeme do něj vložit zprávu o načítání nebo indikátor, který se zobrazí, zatímco se aplikace načítá.
Dále přidáme pod tento prvek HTML šablonu pro přihlašovací stránku. Prozatím do ní vložíme pouze nadpis a sekci obsahující odkaz, který použijeme k navigaci.
<template id="login">
<h1>Bank App</h1>
<section>
<a href="/dashboard">Login</a>
</section>
</template>
Poté přidáme další HTML šablonu pro stránku dashboardu. Tato stránka bude obsahovat různé sekce:
- Hlavičku s nadpisem a odkazem pro odhlášení
- Aktuální zůstatek na bankovním účtu
- Seznam transakcí, zobrazený v tabulce
<template id="dashboard">
<header>
<h1>Bank App</h1>
<a href="/login">Logout</a>
</header>
<section>
Balance: 100$
</section>
<section>
<h2>Transactions</h2>
<table>
<thead>
<tr>
<th>Date</th>
<th>Object</th>
<th>Amount</th>
</tr>
</thead>
<tbody></tbody>
</table>
</section>
</template>
Tip: při vytváření HTML šablon, pokud chcete vidět, jak budou vypadat, můžete zakomentovat řádky
<template>
a</template>
tím, že je obklopíte<!-- -->
.
✅ Proč myslíte, že používáme atributy id
na šablonách? Mohli bychom použít něco jiného, například třídy?
Zobrazení šablon pomocí JavaScriptu
Pokud zkusíte aktuální HTML soubor v prohlížeči, uvidíte, že se zasekne na zobrazení Loading...
. To je proto, že musíme přidat nějaký JavaScriptový kód, který instancuje a zobrazí HTML šablony.
Instancování šablony se obvykle provádí ve 3 krocích:
- Získání elementu šablony v DOM, například pomocí
document.getElementById
. - Klonování elementu šablony pomocí
cloneNode
. - Připojení k DOM pod viditelný prvek, například pomocí
appendChild
.
✅ Proč musíme šablonu klonovat, než ji připojíme k DOM? Co si myslíte, že by se stalo, kdybychom tento krok přeskočili?
Úkol
Vytvořte nový soubor nazvaný app.js
ve složce svého projektu a importujte tento soubor do sekce <head>
svého HTML:
<script src="app.js" defer></script>
Nyní v app.js
vytvoříme novou funkci updateRoute
:
function updateRoute(templateId) {
const template = document.getElementById(templateId);
const view = template.content.cloneNode(true);
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);
}
To, co zde děláme, jsou přesně 3 kroky popsané výše. Instancujeme šablonu s id
templateId
a vložíme její klonovaný obsah do našeho zástupce aplikace. Všimněte si, že musíme použít cloneNode(true)
, abychom zkopírovali celý podstrom šablony.
Nyní zavolejte tuto funkci s jednou ze šablon a podívejte se na výsledek.
updateRoute('login');
✅ Jaký je účel tohoto kódu app.innerHTML = '';
? Co se stane bez něj?
Vytváření tras
Když mluvíme o webové aplikaci, nazýváme trasování záměr mapovat URL na konkrétní obrazovky, které by měly být zobrazeny. Na webové stránce s více HTML soubory se to děje automaticky, protože cesty k souborům se odrážejí v URL. Například s těmito soubory ve složce vašeho projektu:
mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html
Pokud vytvoříte webový server s mywebsite
jako kořen, mapování URL bude:
https://site.com --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
Nicméně pro naši webovou aplikaci používáme jeden HTML soubor obsahující všechny obrazovky, takže nám toto výchozí chování nepomůže. Musíme tuto mapu vytvořit ručně a aktualizovat zobrazenou šablonu pomocí JavaScriptu.
Úkol
Použijeme jednoduchý objekt k implementaci mapy mezi cestami URL a našimi šablonami. Přidejte tento objekt na začátek svého souboru app.js
.
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard' },
};
Nyní trochu upravíme funkci updateRoute
. Místo toho, abychom přímo předávali templateId
jako argument, chceme ho získat nejprve pohledem na aktuální URL a poté použít naši mapu k získání odpovídající hodnoty templateId
. Můžeme použít window.location.pathname
k získání pouze části cesty z URL.
function updateRoute() {
const path = window.location.pathname;
const route = routes[path];
const template = document.getElementById(route.templateId);
const view = template.content.cloneNode(true);
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);
}
Zde jsme mapovali trasy, které jsme deklarovali, na odpovídající šablonu. Můžete vyzkoušet, že to funguje správně, změnou URL ručně ve svém prohlížeči.
✅ Co se stane, když zadáte neznámou cestu do URL? Jak bychom to mohli vyřešit?
Přidání navigace
Dalším krokem pro naši aplikaci je přidání možnosti navigace mezi stránkami bez nutnosti ručně měnit URL. To zahrnuje dvě věci:
- Aktualizaci aktuálního URL
- Aktualizaci zobrazené šablony na základě nového URL
Druhou část jsme již vyřešili pomocí funkce updateRoute
, takže musíme zjistit, jak aktualizovat aktuální URL.
Budeme muset použít JavaScript a konkrétně history.pushState
, který umožňuje aktualizovat URL a vytvořit nový záznam v historii prohlížení, aniž by se znovu načítalo HTML.
Poznámka: Zatímco HTML prvek kotvy
<a href>
může být použit samostatně k vytvoření hypertextových odkazů na různé URL, ve výchozím nastavení způsobí, že prohlížeč znovu načte HTML. Je nutné tomuto chování zabránit při manipulaci s trasováním pomocí vlastního JavaScriptu, použitím funkce preventDefault() na události kliknutí.
Úkol
Vytvořme novou funkci, kterou můžeme použít k navigaci v naší aplikaci:
function navigate(path) {
window.history.pushState({}, path, path);
updateRoute();
}
Tato metoda nejprve aktualizuje aktuální URL na základě zadané cesty a poté aktualizuje šablonu. Vlastnost window.location.origin
vrací kořen URL, což nám umožňuje rekonstruovat kompletní URL ze zadané cesty.
Nyní, když máme tuto funkci, můžeme se postarat o problém, který máme, pokud cesta neodpovídá žádné definované trase. Upravením funkce updateRoute
přidáme záložní trasu na jednu z existujících tras, pokud nemůžeme najít shodu.
function updateRoute() {
const path = window.location.pathname;
const route = routes[path];
if (!route) {
return navigate('/login');
}
...
Pokud nelze najít trasu, nyní přesměrujeme na stránku login
.
Nyní vytvořme funkci pro získání URL při kliknutí na odkaz a zabránění výchozímu chování prohlížeče při kliknutí na odkaz:
function onLinkClick(event) {
event.preventDefault();
navigate(event.target.href);
}
Dokončeme navigační systém přidáním vazeb na naše odkazy Login a Logout v HTML.
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>
Objekt event
výše zachytí událost click
a předá ji naší funkci onLinkClick
.
Pomocí atributu onclick
připojte událost click
k JavaScriptovému kódu, zde volání funkce navigate()
.
Zkuste kliknout na tyto odkazy, nyní byste měli být schopni navigovat mezi různými obrazovkami své aplikace.
✅ Metoda history.pushState
je součástí standardu HTML5 a je implementována ve všech moderních prohlížečích. Pokud vytváříte webovou aplikaci pro starší prohlížeče, existuje trik, který můžete použít místo této API: použití hash (#
) před cestou vám umožní implementovat trasování, které funguje s běžnou navigací kotvy a nenačítá stránku znovu, protože jeho účelem bylo vytvořit interní odkazy na stránce.
Řešení tlačítek zpět a vpřed v prohlížeči
Použití history.pushState
vytváří nové záznamy v historii navigace prohlížeče. Můžete to zkontrolovat podržením tlačítka zpět svého prohlížeče, mělo by zobrazit něco jako toto:
Pokud zkusíte několikrát kliknout na tlačítko zpět, uvidíte, že se aktuální URL mění a historie se aktualizuje, ale stále se zobrazuje stejná šablona.
To je proto, že aplikace neví, že je potřeba zavolat updateRoute()
pokaždé, když se historie změní. Pokud se podíváte na dokumentaci history.pushState
, můžete vidět, že pokud se stav změní - což znamená, že jsme se přesunuli na jiné URL - je spuštěna událost popstate
. Použijeme to k vyřešení tohoto problému.
Úkol
Abychom zajistili, že zobrazená šablona bude aktualizována, když se historie prohlížeče změní, připojíme novou funkci, která volá updateRoute()
. Uděláme to na konci našeho souboru app.js
:
window.onpopstate = () => updateRoute();
updateRoute();
Poznámka: zde jsme použili arrow function k deklaraci našeho obslužného programu události
popstate
pro stručnost, ale běžná funkce by fungovala stejně.
Zde je video o arrow funkcích:
🎥 Klikněte na obrázek výše pro video o arrow funkcích.
Nyní zkuste použít tlačítka zpět a vpřed svého prohlížeče a zkontrolujte, že zobrazená trasa je tentokrát správně aktualizována.
🚀 Výzva
Přidejte novou šablonu a trasu pro třetí stránku, která zobrazuje kredity této aplikace.
Kvíz po lekci
Přehled a samostudium
Trasování je jednou z překvapivě složitých částí vývoje webu, zejména když se web přesouvá od chování při obnovování stránky k obnovování stránky v aplikacích typu Single Page Application. Přečtěte si něco o tom, jak služba Azure Static Web App řeší trasování. Dokážete vysvětlit, proč jsou některá rozhodnutí popsaná v tomto dokumentu nezbytná?
Zadání
Prohlášení:
Tento dokument byl přeložen pomocí služby pro automatický překlad Co-op Translator. I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.