Lekce 1 - Blazor - .NET Core SPA s C# .NET i na straně klienta
Posledních několik let se věnuji vývoji .NET webových aplikací s architekturou MVC a dívám se po nějakých novějších technologiích. Ano, .NET nahrazuje .NET Core a EF zase EF Core, ale přiznám se, že z mého pohledu se zas tolik nezměnilo a vývoj vypadá vcelku podobně.
Spousta klientů si přeje takové ty "rychlejší" stránky, kde s každým kliknutím nemusíte přenačítat celý obsah a na to není MVC úplně stavěné. Máme možnost vrhnout se do psaní JavaScriptů na klientovi a používat AJAX nebo začít psát klienta s pomocí Angular, Vue či podobných JS nadstaveb. V každém případě musíme objevovat svět odlišný od .NETu. Ne, že by na tom bylo něco špatného. Říká se "kolik jazyků znáš, tolikrát jsi programátorem". Ale stojí to spoustu času a ne každý ho má
Blazor
Když Microsoft přišel s frameworkem Blazor, řekl jsem si, že to by mohla být přesně ta cesta, kterou hledám. Umožňuje totiž:
- interaktivní uživatelské rozhraní pomocí jazyka C# namísto JavaScriptu
- sdílení logiky aplikace na straně serveru a klienta napsané v .NET
- využití stávajících .NET knihoven
Vytvoření nové aplikace
Ve Visual Studio zvolme Create a new project a šablonu Blazor App. Po tradičním zadání názvu projektu dostaneme na další stránce průvodce na výběr mezi variantami Blazor Server App a Blazor WebAssembly App.
Blazor WebAssembly App chápu jako plnohodnotnou SPA (aplikace běží přímo na klientovi), zatímco první varianta běží na serveru a chování SPA simuluje s pomocí technologie SignalR. Z toho mohou vyplynout i výhody/nevýhody každé z variant. Zatímco u serverového typu Blazoru by mělo být rychlejší počáteční načtení aplikace, jednotlivé akce v aplikaci mohou mít o něco pomalejší odezvu z důvodu nutnosti neustálé komunikace se serverem. U WebAssembly by to mělo být přesně obráceně - delší načítání aplikace, ale rychlejší odezvy. Navíc musí prohlížeč uživatele podporovat technologii WebAssembly.
Spuštění aplikace
Já zvolím pro začátek Server App, protože tato technologie byla oficiálně vydána první. Šablona aplikace již obsahuje tři jednoduché stránky jako příklady použití, takže ji zkusme hned spustit a uvidíme funkční aplikaci se stránkami:
- Home - jednoduchá stránka s komponentou, ale bez vlastního kódu
- Counter - stránka zobrazující obsah proměnné a možností zvýšení hodnoty proměnné kliknutím na tlačítko
- Fetch data - stránka zobrazující data získaná ze služby inicializované s pomocí Dependency Injection
Struktura aplikace
Struktura šablony aplikace je poměrně jednoduchá. V Solution Exploreru najdeme následující složky:
wwwroot/
- obsahuje soubory s kaskádovými styly a JavaScriptData/
- obsahuje model a servisu pro zobrazovaná data na poslední stránce (ve větších aplikacích možná budou tyto soubory v jiných vrstvách - datové resp. business, v menších aplikacích bych je stejně minimálně oddělil do nových složek, např.Model/
aService/
)Pages/
- pro jednotlivé stránky výsledné aplikaceShared/
- pro komponenty, které můžeme napříč stránkami sdílet
Kromě toho v rootu aplikace najdeme soubory jako Startup.cs
,
Program.cs
a appsettings.json
, které už byste měli
znát z předchozích typů .NET Core
aplikací. Pokud je neznáte, na ITnetworku se o nich určitě dočtete v
jiných kurzech, takže to zde nebudeme opakovat. Zajímavým pro nás bude
soubor _Imports.razor
, kam si budeme přidávat další jmenné
prostory, které budeme chtít v aplikaci využívat.
Základ celé aplikace nalezneme v souboru _Host.cshtml
, což je
vlastně webová stránka. V ní je odkaz na soubor App.razor
, kde
se zajišťuje routování. Ani jeden z těchto souborů zatím nebudeme
upravovat. V souboru App.razor
je jako výchozí layout definována
komponenta MainLayout.razor
a v ní už vidíme vzhled naší
aplikace - menu s pomocí komponenty NavMenu.razor
, horní řádek
s odkazem a část pro tělo aplikace (<body>
).
První úpravy
Hello world! už v šabloně máme, tak musíme vymyslet něco
sofistikovanějšího. Pro první seznámení s frameworkem Blazor jsem tedy
zvolil jednoduchý příklad - seznam úkolů. Každý úkol bude samostatnou
komponentou, začněme tedy vytvořením nové komponenty
TodoItem
.
Pravým tlačítkem myši nad složkou Shared/
(protože
komponenty jsou znovupoužitelné a patří právě tam) vyvoláme kontextové
menu a zvolíme Add -> New item... -> Razor component nebo
přímo Add -> Razor component (pokud máte jako já v nabídce).
Komponentu pojmenujeme TodoItem
.
Každá komponenta má část s HTML kódem a část se C# kódem, které jsou od sebe oddělené (vlastně se mohou nacházet i v různých souborech). Naše nová komponenta bude obsahovat text úkolu a informaci, zda je úkol splněn nebo ne. Její obsah bude následující:
<div> <input type="checkbox" /> Naučit se Blazor na ITnetwork </div>
První verze komponenty žádný C# kód neobsahuje, takže část
@code
můžeme odstranit úplně. Samozřejmě tato komponenta
neumí zatím nic než zobrazit příslušný HTML kód. Což si hned
ověříme. V souboru Index.razor
nahradíme stávající obsah
(kromě prvního řádku) zavoláním naší nové komponenty:
<TodoItem/>
Aplikaci spustíme, výsledek by měl vypadat nějak takto:
Druhá verze - Parametry
Aby byla komponenta znovupoužitelná, musí být samozřejmě "chytřejší". Přidáme si tedy do naší komponenty dva parametry, konkrétně:
- zobrazovaný text a
- údaj, zda je úkol splněný nebo ne.
Příslušně tomu musíme samozřejmě také upravit aktuální HTML kód:
<div> <input type="checkbox" checked="@Done"/> <span>@Text</span> </div> @code{ [Parameter] public string Text { get; set; } = "Naučit se Blazor na ITnetwork"; [Parameter] public bool Done { get; set; } = false; }
Je dobré nastavovat parametrům výchozí hodnoty, protože naplnění parametrů při použití komponenty není povinné.
Nyní už můžeme úpravou souboru Index.razor
zobrazit více
rozdílných položek našeho seznamu úkolů například takto:
<TodoItem/> <TodoItem Text="Vytvořit vlastní Blazor aplikaci" /> <TodoItem Text="Pochopit práci s parametry komponenty" Done="true"/>
Třetí verze - Styl
V poslední dnešní verzi komponenty si přidáme nový styl pro splněné
úkoly. Takové úkoly budeme zobrazovat přeškrtnutým písmem. Do komponenty
přidáme textovou proměnnou textStyle
, jejíž hodnota se bude
odvozovat od hodnoty vlastnosti Done
a bude ovlivňovat styl
zobrazeného textu:
<div> <input type="checkbox" checked="@Done"/> <span class="@textStyle">@Text</span> </div> @code{ [Parameter] public string Text { get; set; } = "Naučit se Blazor na ITnetwork"; [Parameter] public bool Done { get; set; } = false; string textStyle => Done ? "done" : ""; }
A samozřejmě do souboru site.css
musíme přidat definici
nového stylu:
.done { text-decoration:line-through; }
Po spuštění aplikace vypadá vše v pořádku, ale po kliknutí na
libovolný z úkolů zjistíme, že se nový styl na text nepoužije. Důvod je
v jednosměrném bindingu naší vlastnosti Done
na komponentu. V
takovýchto případech se při renderování komponenty použije hodnota
proměnné, ale změna stavu komponenty na stránce se už nepřenese zpět do
proměnné. Proto musíme změnit binding na obousměrný:
... <input type="checkbox" @bind="Done"/> ...
Nyní si můžeme vyzkoušet, že se styl textu se zaškrtnutím komponenty opravdu změní. No není to krásné bez kousku JavaScriptu?
To je pro dnešek vše. Pokud bude o tento článek zájem a v komentářích se objeví konstruktivní kritika, pokusím se pokračovat další lekcí
Přeji hodně programátorských úspěchů!
V další lekci, Blazor - Rozšíření Todo aplikace v .NET Core SPA, budeme v naší Todo aplikaci pokračovat a ukážeme si, jak správně reagovat na události.