Læringsmål
- Implementere Master/Detail over API-data (Pokémon-liste + detail).
- Vælge mellem CSS grid, Bootstrap og MudBlazor til layout.
- Forklare async I/O vs
Task.Run/ manuelle threads i UI. - Genkende Wizard, Modal confirm og List+filter patterns.
Hvornår Master/Detail? Når brugeren sammenligner mange items (Pokémon, champions) og skal se detail uden ny route — eller kombiner med routing for bookmarkbart id.
Tjek dig selv før du går videre
- Du kan beskrive Master/Detail med Pokémon eller LoL.
- Du ved hvorfor async ikke blokerer UI-tråden på Server.
- Du har gennemgået async-lab på siden.
Layout containers strukturerer siden: sidebar + content, topnav + main. I undervisningen kombineres ofte Bootstrap grid med komponent-opdeling.
Master/Detail
Venstre liste (master) vælger id; højre panel (detail) henter /go/pokemon/{id} eller viser cached DTO. State (selectedId) bor i parent — child får parametre.
<div class="row">
<div class="col-md-4">
<PokemonList Items="mons" OnSelect="id => selectedId = id" />
</div>
<div class="col-md-8">
@if (selectedId is int sid)
{
<PokemonDetail Id="sid" />
}
</div>
</div>
- Parent holder
selectedIdog loading-state. - Detail child bruger
OnParametersSetAsync+ CancellationToken. - Vis «Vælg et element» når
selectedIder null — undgå tom højre kolonne uden forklaring.
List + filter
Søgefelt + @bind på filterstreng; enten client-side LINQ på hentet liste eller debounced API-kald. LoL-champions med rolle-filter er klassisk eksamen-case.
Hvornår client vs server filter? Under ~200 items hentet én gang: LINQ i memory. Store datasæt eller server-side søgning: debounce + query mod OpgaverAPI.
MudBlazor
MudBlazor leverer MudTable, MudDialog, MudTextField, theming. Install NuGet, tilføj i Program.cs:
builder.Services.AddMudServices();
Wrap layout med MudThemeProvider, MudPopoverProvider, MudDialogProvider. Godt når I vil matche moderne admin-UI uden at skrive al CSS selv — se mudblazor.com.
Hvornår MudBlazor frem for rå Bootstrap? Tabeller med sort/paginering, dialogs og snackbars — sparer tid i GUI-eksamen; lær stadig HTML/CSS-grundlag i razor-lektionen.
Async — ikke threads i UI
Web-UI venter på netværk. await Http.GetFromJsonAsync frigiver tråden så Server-circuit kan betjene andre events. Task.Run flytter CPU-arbejde til thread pool — sjældent brugt til API-kald; på WASM begrænset.
Async-tidslinje (UI)
Se forskellen på await (responsiv UI) vs blokering.
- Event: «Hent Star Wars personer»
- UI viser spinner (state)
- await Http — andre klik kan stadig queues (Server)
- Resultat bindes til MudTable / HTML table
- Spinner skjules
Faldgrube: .Result eller .Wait() på async Task i UI — deadlock/race på Blazor Server. Brug async hele vejen.
Modal confirm
Slet favorit? MudDialog eller simpel conditional render + fokus-trap. Bekræft før DELETE mod API.
Trin: bruger klikker Slet → modal → ved OK kald await Api.DeleteAsync(id) → ved success luk modal og opdater liste; ved fejl vis ProblemDetails-tekst i dialog.
Quiz 1
Hvad er typisk mønster for Pokémon-liste + detailpanel?
Quiz 2
Hvordan venter I bedst på OpgaverAPI i en event handler?
Hvorfor det betyder noget: Master/Detail er standard for Pokémon-dex og LoL-picker — samme mønster som desktop GUI-fag.
Sådan fejler det i praksis: Blocking .Result på Http i event — fryser Blazor Server UI for alle på circuit.
Mini-opgave
Master/Detail mod API med loading og tom-state «Vælg champion».
Quiz 3
Hent LoL-liste uden at fryse UI?
Læs hos Microsoft
Prøv med API
Baseret på MAGS Blazor-wiki og Microsoft Learn — Blazor.