|
|
1 month ago | |
|---|---|---|
| .. | ||
| README.md | 1 month ago | |
| assignment.md | 4 months ago | |
README.md
Byg en bank-app del 3: Metoder til at hente og bruge data
Tænk på Enterprises computer i Star Trek – når kaptajn Picard spørger efter skibets status, dukker informationen straks op uden at hele interfacet lukker ned og genopbygger sig selv. Den fejlfri informationsstrøm er præcis det, vi bygger her med dynamisk datahentning.
Lige nu er din bankapp som en trykt avis – informativ, men statisk. Vi vil forvandle den til noget mere som NASA's mission control, hvor data strømmer kontinuerligt og opdateres i realtid uden at afbryde brugerens arbejdsflow.
Du vil lære at kommunikere asynkront med servere, håndtere data, der ankommer på forskellige tidspunkter, og omdanne rå information til noget meningsfuldt for dine brugere. Det er forskellen på en demo og et produktionsklart software.
⚡ Hvad du kan nå på de næste 5 minutter
Hurtigstartvej for travle udviklere
flowchart LR
A[⚡ 5 minutter] --> B[Opsæt API-server]
B --> C[Test hent med curl]
C --> D[Opret loginfunktion]
D --> E[Se data i aktion]
- Minut 1-2: Start din API-server (
cd api && npm start) og test forbindelsen - Minut 3: Opret en basal
getAccount()funktion ved brug af fetch - Minut 4: Kobl loginformularen til med
action="javascript:login()" - Minut 5: Test login og se kontodata dukke op i konsollen
Hurtige testkommandoer:
# Bekræft, at API kører
curl http://localhost:5000/api
# Test hentning af kontodata
curl http://localhost:5000/api/accounts/test
Hvorfor det betyder noget: På 5 minutter vil du opleve magien ved asynkron datahentning, som driver alle moderne webapplikationer. Det er fundamentet, der får apps til at føles hurtige og levende.
🗺️ Din læringsrejse gennem datadrevne webapplikationer
journey
title Fra statiske sider til dynamiske applikationer
section Forstå udviklingen
Traditionelle sideopdateringer: 3: You
Opdag fordelene ved AJAX/SPA: 5: You
Behersk Fetch API-mønstre: 7: You
section Opbygning af autentifikation
Opret loginfunktioner: 4: You
Håndter asynkrone operationer: 6: You
Administrer brugersessioner: 8: You
section Dynamiske UI-opdateringer
Lær DOM-manipulation: 5: You
Byg transaktionsvisninger: 7: You
Opret responsivt dashboards: 9: You
section Professionelle mønstre
Skabelonbaseret rendering: 6: You
Fejlhåndteringsstrategier: 7: You
Ydeevneoptimering: 8: You
Dit læringsmål: Ved slutningen af denne lektion vil du forstå, hvordan moderne webapplikationer henter, behandler og viser data dynamisk og skaber de fejlfri brugeroplevelser, vi forventer af professionelle applikationer.
Præ-forelæsning quiz
Forudsætninger
Før du dykker ned i datahentning, skal du have disse komponenter klar:
- Forrige lektion: Færdiggør Login- og registreringsformularen – vi bygger videre på denne base
- Lokal server: Installer Node.js og kør API-serveren for at levere kontodata
- API-forbindelse: Test din serverforbindelse med denne kommando:
curl http://localhost:5000/api
# Forventet svar: "Bank API v1.0.0"
Denne hurtige test sikrer, at alle komponenter kommunikerer korrekt:
- Verificerer, at Node.js kører korrekt på dit system
- Bekræfter at din API-server er aktiv og svarer
- Validerer, at din app kan nå serveren (som at tjekke radiokontakt før en mission)
🧠 Overblik over datastyringsøkosystemet
mindmap
root((Data Management))
Authentication Flow
Login Process
Form Validation
Credential Verification
Session Management
User State
Global Account Object
Navigation Guards
Fejl Håndtering
API Communication
Fetch Patterns
GET Requests
POST Requests
Fejl Svar
Data Formats
JSON Processing
URL Encoding
Response Parsing
Dynamic UI Updates
DOM Manipulation
Safe Text Updates
Element Creation
Template Cloning
User Experience
Real-time Updates
Fejl Beskeder
Loading States
Security Considerations
XSS Prevention
textContent Usage
Input Sanitization
Safe HTML Creation
CORS Handling
Cross-Origin Requests
Header Configuration
Development Setup
Kerneprincip: Moderne webapplikationer er dataorkestreringssystemer – de koordinerer mellem brugerflader, server-API’er og browserens sikkerhedsmodeller for at skabe fejlfri og responsive oplevelser.
Forståelse af datahentning i moderne webapps
Måden webapplikationer håndterer data på har ændret sig dramatisk de sidste to årtier. At forstå denne udvikling hjælper dig med at værdsætte, hvorfor moderne teknikker som AJAX og Fetch API er så kraftfulde, og hvorfor de er blevet uundværlige værktøjer for webudviklere.
Lad os udforske, hvordan traditionelle websites fungerede sammenlignet med de dynamiske, responsive applikationer, vi bygger i dag.
Traditionelle multi-side applikationer (MPA)
I de tidlige dage af webben var hvert klik som at skifte kanal på et gammelt fjernsyn – skærmen blev sort, og så sad man og ventede på den nye side. Det var virkeligheden for tidlige webapplikationer, hvor hver interaktion betød, at hele siden blev genopbygget fra bunden.
sequenceDiagram
participant User
participant Browser
participant Server
User->>Browser: Klikker på link eller indsender formular
Browser->>Server: Anmoder om ny HTML-side
Note over Browser: Siden bliver blank
Server->>Browser: Returnerer komplet HTML-side
Browser->>User: Viser ny side (flash/genindlæsning)
Hvorfor denne tilgang føltes klodset:
- Hvert klik betød, at hele siden skulle bygges op fra bunden
- Brugerne blev forstyrret midt i tankerne af de irriterende sideblink
- Dit internet arbejdede overtid med at downloade den samme header og footer igen og igen
- Apps føltes mere som at bladre i et arkivskab end at bruge software
Moderne single-page applikationer (SPA)
AJAX (Asynchronous JavaScript and XML) ændrede paradigmet fuldstændigt. Ligesom den modulopbyggede design af Den Internationale Rumstation, hvor astronauter kan udskifte enkeltkomponenter uden at bygge hele strukturen om, tillader AJAX os at opdatere specifikke dele af en webside uden at genindlæse hele siden. På trods af navnet, der inkluderer XML, bruger vi mest JSON i dag, men grundprincippet er det samme: opdater kun det, der skal ændres.
sequenceDiagram
participant User
participant Browser
participant JavaScript
participant Server
User->>Browser: Interagerer med side
Browser->>JavaScript: Udløser hændelsesbehandler
JavaScript->>Server: Henter kun nødvendige data
Server->>JavaScript: Returnerer JSON-data
JavaScript->>Browser: Opdaterer specifikke sideelementer
Browser->>User: Viser opdateret indhold (ingen genindlæsning)
Hvorfor SPAs føles meget bedre:
- Kun de dele, der rent faktisk ændrer sig, opdateres (smart, ikke?)
- Ingen mere forstyrrende afbrydelser – dine brugere forbliver i deres flow
- Mindre data over nettet betyder hurtigere indlæsning
- Alting føles hurtigt og responsivt, som apps på din telefon
Udviklingen til moderne Fetch API
Moderne browsere tilbyder Fetch API, som erstatter den ældre XMLHttpRequest. Som forskellen på at bruge telegraf og sende email, bruger Fetch API promises for renere asynkron kode og håndterer JSON naturligt.
| Funktion | XMLHttpRequest | Fetch API |
|---|---|---|
| Syntax | Kompleks callback-baseret | Ren promise-baseret |
| JSON-håndtering | Kræver manuel parsing | Indbygget .json() metode |
| Fejlhåndtering | Begrænset fejlinfo | Omfattende fejlbeskrivelser |
| Moderne support | Bagudkompatibel | ES6+ promises og async/await |
💡 Browserkompatibilitet: Godt nyt – Fetch API virker i alle moderne browsere! Hvis du er nysgerrig på specifikke versioner, har caniuse.com hele kompatibilitetshistorikken.
Kort sagt:
- Virker fantastisk i Chrome, Firefox, Safari og Edge (faktisk overalt, hvor dine brugere er)
- Kun Internet Explorer har behov for ekstra hjælp (og ærligt talt, det er tid at sige farvel til IE)
- Forbereder dig perfekt til elegante async/await-mønstre, vi bruger senere
Implementering af brugerlogin og datahentning
Lad os nu implementere loginsystemet, der forvandler din bankapp fra en statisk visning til en funktionel applikation. Ligesom autentifikationsprotokoller i sikre militære faciliteter, skal vi bekræfte brugerens oplysninger og derefter give adgang til deres specifikke data.
Vi bygger dette trinvis, starter med basal autentifikation og tilføjer derefter datahentningsfunktionaliteten.
Trin 1: Opret grundlaget for login-funktionen
Åbn din app.js fil og tilføj en ny login funktion. Den skal håndtere brugerautentifikationen:
async function login() {
const loginForm = document.getElementById('loginForm');
const user = loginForm.user.value;
}
Lad os bryde det ned:
- Det
asyncnøgleord? Det fortæller JavaScript "denne funktion kan komme til at skulle vente på noget" - Vi henter vores form fra siden (intet fancy, bare finder den via dens ID)
- Så trækker vi den indtastede brugernavn-værdi ud
- Her er et smart trick: du kan få adgang til et hvilket som helst input i en form via dens
nameattribut – ingen behov for ekstra getElementById kald!
💡 Form-adgangsmønster: Alle formkontroller kan tilgås via deres navn (sat i HTML med
nameattributten) som egenskaber på form-elementet. Det giver en ren og læsbar måde at hente formdata på.
Trin 2: Opret kontodata-hentningsfunktionen
Dernæst opretter vi en dedikeret funktion til at hente kontodata fra serveren. Den følger samme mønster som din registreringsfunktion, men fokuserer på dataindhentning:
async function getAccount(user) {
try {
const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user));
return await response.json();
} catch (error) {
return { error: error.message || 'Unknown error' };
}
}
Det her opnår koden:
- Bruger det moderne
fetchAPI til at anmode om data asynkront - Bygger en GET-forespørgsel med brugernavn som parameter
- Anvender
encodeURIComponent()for sikkert at håndtere specialtegn i URL’er - Konverterer svaret til JSON-format for nem datahåndtering
- Håndterer fejl elegant ved at returnere et fejlobjekt i stedet for at crashe
⚠️ Sikkerhedsnote:
encodeURIComponent()håndterer specialtegn i URL’er. Ligesom kodningssystemer brugt i marinekommunikation sikrer den, at din besked ankommer ubeskadiget, og forhindrer at tegn som "#" eller "&" fejltolkes.
Hvorfor det er vigtigt:
- Forhindrer specialtegn i at bryde URL’er
- Beskytter mod URL-manipulationsangreb
- Sikrer at serveren modtager de forventede data
- Følger sikre udviklingsprincipper
Forståelse af HTTP GET-forespørgsler
Her er noget, der måske overrasker dig: når du bruger fetch uden ekstra indstillinger, laver den automatisk en GET forespørgsel. Det passer perfekt til, hvad vi laver – spørger serveren "hey, kan jeg se denne brugers kontodata?"
Tænk på GET som høfligt at låne en bog på biblioteket – du beder om noget, der allerede findes. POST-forespørgsler (som vi brugte ved registrering) svarer mere til at indsende en ny bog til samlingen.
| GET-forespørgsel | POST-forespørgsel |
|---|---|
| Formål | Hente eksisterende data |
| Parametre | I URL-sti/spørgestreng |
| Caching | Kan caches af browsere |
| Sikkerhed | Synlige i URL/logfiler |
sequenceDiagram
participant B as Browser
participant S as Server
Note over B,S: GET Anmodning (Datahentning)
B->>S: GET /api/accounts/test
S-->>B: 200 OK + Kontodata
Note over B,S: POST Anmodning (Dataindsendelse)
B->>S: POST /api/accounts + Nye kontodata
S-->>B: 201 Oprettet + Bekræftelse
Note over B,S: Fejlhåndtering
B->>S: GET /api/accounts/nonexistent
S-->>B: 404 Ikke fundet + Fejlmeddelelse
Trin 3: Samling af det hele
Nu til den tilfredsstillende del – lad os forbinde din konto-hentningsfunktion med login-processen. Her klikker det hele sammen:
async function login() {
const loginForm = document.getElementById('loginForm');
const user = loginForm.user.value;
const data = await getAccount(user);
if (data.error) {
return console.log('loginError', data.error);
}
account = data;
navigate('/dashboard');
}
Denne funktion følger en klar rækkefølge:
- Trækker brugernavnet ud fra form-inputtet
- Anmoder om brugerkontoens data fra serveren
- Håndterer eventuelle fejl undervejs
- Gemmer kontodata og navigerer til dashboard ved succes
🎯 Async/Await-mønster: Da
getAccounter asynkron, bruger viawaitnøgleordet for at vente på serverens svar, inden koden fortsætter. Det forhindrer, at koden læser udefinerede data.
Trin 4: Opret et hjem til dine data
Din app har brug for et sted at huske kontoinformationen, når den er hentet. Tænk på det som din apps korttidshukommelse – et sted at holde styr på den nuværende brugers data. Tilføj denne linje øverst i din app.js fil:
// Dette indeholder den aktuelle brugers kontodata
let account = null;
Hvorfor vi skal bruge det:
- Holder kontodata tilgængelig overalt i appen
- Starter med
null, som betyder "ingen er logget ind endnu" - Opdateres, når en bruger logger ind eller registrerer sig med succes
- Fungerer som en enkelt sandhedskilde – ingen forvirring om, hvem der er logget ind
Trin 5: Kobl din formular til
Lad os nu forbinde din flotte nye loginfunktion til din HTML-formular. Opdater dit form-tag sådan her:
<form id="loginForm" action="javascript:login()">
<!-- Your existing form inputs -->
</form>
Hvad denne lille ændring gør:
- Stopper formen fra at genindlæse hele siden som standard
- Kalder din brugerdefinerede JavaScript-funktion i stedet
- Holder alt glat og SPA-lignende
- Giver dig fuld kontrol over, hvad der sker, når brugerne klikker "Login"
Trin 6: Forbedr din registreringsfunktion
For konsistens, opdater også din register funktion til at gemme kontodata og navigere til dashboardet:
// Tilføj disse linjer i slutningen af din registreringsfunktion
account = result;
navigate('/dashboard');
Denne forbedring giver:
- Problemfri overgang fra registrering til dashboard
- Konsistent brugeroplevelse mellem login- og registreringsflow
- Øjeblikkelig adgang til kontodata efter en succesfuld registrering
Test af din implementering
flowchart TD
A[Bruger indtaster legitimationsoplysninger] --> B[Login-funktion kaldt]
B --> C[Hent kontodata fra server]
C --> D{Data modtaget succesfuldt?}
D -->|Ja| E[Gem kontodata globalt]
D -->|Nej| F[Vis fejlmeddelelse]
E --> G[Naviger til dashboard]
F --> H[Bruger forbliver på login-side]
Tid til at prøve det af:
- Opret en ny konto for at sikre, at alt fungerer
- Prøv at logge ind med de samme oplysninger
- Kig i browserens konsol (F12) hvis noget virker mærkeligt
- Bekræft at du kommer ind på dashboardet efter succesfuld login
Hvis noget ikke virker, så panik ikke! De fleste problemer er simple fejl som tastefejl eller glemt at starte API-serveren.
En hurtig bemærkning om Cross-Origin magi
Du tænker måske: "Hvordan kan min webapp tale med denne API-server, når de kører på forskellige porte?" Godt spørgsmål! Det kommer vi alle webudviklere til at støde på.
🔒 Cross-Origin Sikkerhed: Browsere håndhæver en "same-origin policy" for at forhindre uautoriseret kommunikation mellem forskellige domæner. Ligesom checkpointsystemet ved Pentagon verifierer de, at kommunikationen er godkendt, før dataoverførsel tillades.
I vores opsætning:
- Din webapp kører på
localhost:3000(udviklingsserver) - Din API-server kører på
localhost:5000(backend-server) - API-serveren inkluderer CORS headers, som eksplicit autoriserer kommunikation fra din webapp
Denne konfiguration afspejler virkelige udviklingsmiljøer, hvor frontend og backend typisk kører på separate servere.
📚 Lær mere: Dyk dybere ned i API’er og datahentning med denne omfattende Microsoft Learn modul om API’er.
Gør dine data levende i HTML
Nu vil vi gøre de hentede data synlige for brugerne via DOM-manipulation. Ligesom processen med at fremkalde fotografier i et mørkekammer, tager vi usynlige data og gengiver dem til noget, brugerne kan se og interagere med. DOM-manipulation er teknikken, der forvandler statiske websider til dynamiske applikationer, som opdaterer deres indhold baseret på brugerinteraktioner og serverrespons.
Valg af det rigtige værktøj til opgaven
Når det kommer til opdatering af dit HTML med JavaScript, har du flere muligheder. Tænk på disse som forskellige værktøjer i en værktøjskasse - hver enkelt perfekt til specifikke opgaver:
| Metode | Hvad den er god til | Hvornår den skal bruges | Sikkerhedsniveau |
|---|---|---|---|
textContent |
Sikker visning af brugerdata | Når du viser tekst | ✅ Stærkt som en klippe |
createElement() + append() |
Bygning af komplekse layouts | Oprettelse af nye sektioner/lister | ✅ Bullitproof |
innerHTML |
Indstilling af HTML-indhold | ⚠️ Prøv at undgå denne | ❌ Risikabelt |
Den sikre måde at vise tekst på: textContent
Egenskaben textContent er din bedste ven, når du viser brugerdata. Det er som at have en dørmand til din side – intet skadeligt slipper igennem:
// Den sikre og pålidelige måde at opdatere tekst på
const balanceElement = document.getElementById('balance');
balanceElement.textContent = account.balance;
Fordele ved textContent:
- Behandler al tekst som almindelig tekst (forhindrer script-eksekvering)
- Rydder automatisk eksisterende indhold
- Effektiv til simple tekstopdateringer
- Giver indbygget sikkerhed mod skadeligt indhold
Oprettelse af dynamiske HTML-elementer
For mere komplekst indhold kan du kombinere document.createElement() med append()-metoden:
// Sikker måde at oprette nye elementer på
const transactionItem = document.createElement('div');
transactionItem.className = 'transaction-item';
transactionItem.textContent = `${transaction.date}: ${transaction.description}`;
container.append(transactionItem);
Forståelse af denne tilgang:
- Opretter nye DOM-elementer programmatisk
- Bevarer fuld kontrol over elementattributter og indhold
- Tillader komplekse, indlejrede elementstrukturer
- Bevarer sikkerheden ved at adskille struktur fra indhold
⚠️ Sikkerhedsovervejelse: Selvom
innerHTMLoptræder i mange vejledninger, kan det eksekvere indlejrede scripts. Ligesom sikkerhedsprotokollerne ved CERN, der forhindrer uautoriseret kodeeksekvering, giver brug aftextContentogcreateElementsikrere alternativer.
Risici ved innerHTML:
- Eksekverer enhver
<script>-tag i brugerdata - Sårbart overfor kodeinjektionsangreb
- Skaber potentielle sikkerhedssårbarheder
- De sikrere alternativer vi bruger tilbyder tilsvarende funktionalitet
Gør fejl brugervenlige
Lige nu vises login-fejl kun i browserens konsol, som brugere ikke kan se. Ligesom forskellen mellem pilotens interne diagnosticering og passagerinformationssystemet, skal vi kommunikere vigtig information via de rette kanaler.
Implementering af synlige fejlbeskeder giver brugerne øjeblikkelig feedback om, hvad der gik galt, og hvordan de skal fortsætte.
Trin 1: Tilføj et sted til fejlmeddelelser
Først giver vi fejlmeddelelser et hjem i dit HTML. Tilføj dette lige før din login-knap, så brugerne naturligt vil se det:
<!-- This is where error messages will appear -->
<div id="loginError" role="alert"></div>
<button>Login</button>
Hvad der sker her:
- Vi opretter en tom container, der forbliver usynlig, indtil den skal bruges
- Den placeres, hvor brugere naturligt kigger efter at have klikket på "Login"
role="alert"er en fin detalje for skærmlæsere - det fortæller hjælpe-teknologi "hey, det her er vigtigt!"- Det unikke
idgiver vores JavaScript en nem målrettet reference
Trin 2: Opret en praktisk hjælpefunktion
Lad os lave en lille hjælpefunktion, der kan opdatere tekst i ethvert element. Det er en af de "skriv én gang, brug alle steder"-funktioner, der sparer dig tid:
function updateElement(id, text) {
const element = document.getElementById(id);
element.textContent = text;
}
Fordele ved funktionen:
- Simpelt interface, der kun kræver et element-ID og tekstindhold
- Finder og opdaterer DOM-elementer sikkert
- Genanvendeligt mønster, der mindsker kode-duplication
- Opretholder ensartet opdateringsadfærd på tværs af applikationen
Trin 3: Vis fejl, hvor brugerne kan se dem
Nu erstatter vi den skjulte konsolbesked med noget, brugerne rent faktisk kan se. Opdater din loginfunktion:
// I stedet for blot at logge til konsollen, vis brugeren hvad der er galt
if (data.error) {
return updateElement('loginError', data.error);
}
Denne lille ændring gør en stor forskel:
- Fejlmeddelelser vises lige, hvor brugerne kigger
- Ikke flere mystiske, tavse fejl
- Brugerne får øjeblikkelig, brugbar feedback
- Din app føles nu professionel og gennemtænkt
Når du nu tester med en ugyldig konto, vil du se en hjælpsom fejlmeddelelse direkte på siden!
Trin 4: Vær inkluderende med tilgængelighed
Her er noget smart ved det role="alert" vi tilføjede tidligere - det er ikke bare pynt! Denne lille attribut skaber et såkaldt Live Region, der straks annoncerer ændringer til skærmlæsere:
<div id="loginError" role="alert"></div>
Hvorfor det betyder noget:
- Skærmlæserbrugere hører fejlmeddelelsen, så snart den vises
- Alle får den samme vigtige information, uanset hvordan de navigerer
- En simpel måde at gøre din app brugbar for flere mennesker
- Viser, at du bekymrer dig om at skabe inkluderende oplevelser
Små detaljer som denne adskiller gode udviklere fra fantastiske!
🎯 Pædagogisk tjek-ind: Autentificeringsmønstre
Pause og refleksion: Du har lige implementeret et komplet autentificeringsflow. Det er et fundamentalt mønster inden for webudvikling.
Hurtig selvevaluering:
- Kan du forklare, hvorfor vi bruger async/await til API-kald?
- Hvad ville ske, hvis vi glemte
encodeURIComponent()-funktionen? - Hvordan forbedrer vores fejlhåndtering brugeroplevelsen?
Reel verden-forbindelse: De mønstre, du har lært her (asynkron datahentning, fejlhåndtering, brugerfeedback) bruges i alle større webapplikationer, fra sociale medieplatforme til e-handelssider. Du opbygger færdigheder på produktionsniveau!
Udfordrende spørgsmål: Hvordan kunne du ændre dette autentificeringssystem til at håndtere flere brugerroller (kunde, administrator, kasserer)? Tænk på dat strukturen og UI-ændringer, der skal til.
Trin 5: Anvend det samme mønster til registrering
For konsekvens, implementer identisk fejlhåndtering i din registreringsformular:
- Tilføj et fejlvisningselement til dit registrerings-HTML:
<div id="registerError" role="alert"></div>
- Opdater din registreringsfunktion til at bruge samme fejldisplaymønster:
if (data.error) {
return updateElement('registerError', data.error);
}
Fordele ved konsekvent fejlhåndtering:
- Sikrer ensartet brugeroplevelse på tværs af alle formularer
- Reducerer mental belastning ved at bruge kendte mønstre
- Forenkler vedligeholdelse med genanvendelig kode
- Sikrer at tilgængelighedsstandarder overholdes over hele appen
Oprettelse af dit dynamiske dashboard
Nu vil vi forvandle dit statiske dashboard til et dynamisk interface, der viser reel kontodata. Ligesom forskellen mellem en trykt flyvetidsplan og de levende afgangstavler i lufthavne, bevæger vi os fra statisk information til realtids-, responsive visninger.
Ved hjælp af de DOM-manipulations teknikker, du har lært, skaber vi et dashboard, der opdaterer sig automatisk med aktuelle kontooplysninger.
Lær dine data at kende
Før vi går i gang med at bygge, lad os kigge på, hvilken slags data din server sender tilbage. Når nogen logger ind med succes, får du en sand skattekiste af information til at arbejde med:
{
"user": "test",
"currency": "$",
"description": "Test account",
"balance": 75,
"transactions": [
{ "id": "1", "date": "2020-10-01", "object": "Pocket money", "amount": 50 },
{ "id": "2", "date": "2020-10-03", "object": "Book", "amount": -10 },
{ "id": "3", "date": "2020-10-04", "object": "Sandwich", "amount": -5 }
]
}
Denne datastruktur indeholder:
user: Perfekt til at personliggøre oplevelsen ("Velkommen tilbage, Sarah!")currency: Sørger for, at vi viser pengebeløb korrektdescription: Et venligt navn for kontoenbalance: Den altafgørende aktuelle saldotransactions: Den komplette historik over transaktioner med alle detaljer
Alt hvad du behøver for at bygge et professionelt bank-dashboard!
flowchart TD
A[Brugerlogin] --> B[Hent kontodata]
B --> C{Data gyldig?}
C -->|Ja| D[Gem i global variabel]
C -->|Nej| E[Vis fejlmeddelelse]
D --> F[Naviger til dashboard]
F --> G[Opdater UI-elementer]
G --> H[Vis saldo]
G --> I[Vis beskrivelse]
G --> J[Gengiv transaktioner]
J --> K[Opret tabelrækker]
K --> L[Formater valuta]
L --> M[Bruger ser live data]
💡 Pro tip: Vil du se dit dashboard i aktion med det samme? Brug brugernavnet
test, når du logger ind – det kommer forudindlæst med eksempeldata, så du kan se alt fungere uden at skulle oprette transaktioner først.
Hvorfor testkontoen er praktisk:
- Kommer allerede med realistiske eksempler
- Perfekt til at se, hvordan transaktioner vises
- God til at teste dine dashboard-funktioner
- Spar dig selv besværet med manuelt at oprette testdata
Oprettelse af dashboard visningselementer
Lad os bygge dit dashboard-interface trin for trin, begyndende med kontosammendraget og derefter gå videre til mere komplekse funktioner som transaktionslister.
Trin 1: Opdater din HTML-struktur
Først udskift det statiske "Balance"-afsnit med dynamiske pladsholdere, som din JavaScript kan udfylde:
<section>
Balance: <span id="balance"></span><span id="currency"></span>
</section>
Dernæst tilføj en sektion for kontobeskrivelsen. Da det fungerer som en titel for dashboard-indholdet, brug semantisk HTML:
<h2 id="description"></h2>
Forstå HTML-strukturen:
- Bruger separate
<span>-elementer til saldo og valuta for individuel kontrol - Anvender unikke ID'er til hvert element til målrettet JavaScript
- Følger semantisk HTML ved at bruge
<h2>til kontobeskrivelsen - Skaber en logisk hierarki for skærmlæsere og SEO
✅ Tilgængelighedsindsigt: Kontobeskrivelsen fungerer som titel for dashboard-indholdet, så den er semantisk markeret som en overskrift. Læs mere om, hvordan overskriftsstruktur påvirker tilgængelighed. Kan du identificere andre elementer på din side, der kunne have gavn af overskriftstags?
Trin 2: Opret dashboard-opdateringsfunktionen
Lav nu en funktion, der fylder dit dashboard med reel kontodata:
function updateDashboard() {
if (!account) {
return navigate('/login');
}
updateElement('description', account.description);
updateElement('balance', account.balance.toFixed(2));
updateElement('currency', account.currency);
}
Trin for trin, hvad denne funktion gør:
- Validerer, at kontodata findes, før den fortsætter
- Omdirigerer uautoriserede brugere tilbage til login-siden
- Opdaterer kontobeskrivelsen med den genanvendelige
updateElement-funktion - Formaterer saldoen, så den altid viser to decimaler
- Viser det korrekte valutasymbol
💰 Valutaformatering: Den
toFixed(2)-metode er en livredder! Den sikrer, at din saldo altid ligner rigtige penge - "75.00" i stedet for bare "75". Dine brugere vil sætte pris på at se velkendt valutaformattering.
Trin 3: Sikr at dit dashboard opdateres
For at sikre, at dit dashboard opdateres med aktuelle data, hver gang nogen besøger det, skal vi hægte os på dit navigationssystem. Hvis du har gennemført lektion 1 opgaven, burde det føles bekendt. Hvis ikke, så bare rolig - her er hvad du skal gøre:
Tilføj dette til slutningen af din updateRoute()-funktion:
if (typeof route.init === 'function') {
route.init();
}
Opdater derefter dine ruter til at inkludere dashboard-initialisering:
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard', init: updateDashboard }
};
Hvad denne smarte opsætning gør:
- Tjekker om en rute har særlig initialiseringskode
- Kører denne kode automatisk, når ruten indlæses
- Sikrer, at dit dashboard altid viser friske, aktuelle data
- Holder din routing-logik ren og organiseret
Test dit dashboard
Efter implementering af disse ændringer, test dit dashboard:
- Log ind med en testkonto
- Bekræft, at du bliver omdirigeret til dashboardet
- Tjek, at kontobeskrivelsen, saldo og valuta vises korrekt
- Prøv at logge ud og ind igen for at sikre, at data opdateres korrekt
Dit dashboard skulle nu vise dynamisk kontoinformation, der opdateres baseret på den indloggede brugers data!
Byg smarte transaktionslister med skabeloner
I stedet for manuelt at skabe HTML for hver transaktion bruger vi skabeloner til automatisk at generere konsekvent formatering. Ligesom standardiserede komponenter brugt i rumfart, sikrer skabeloner, at hver transaktionsrække følger samme struktur og udseende.
Denne teknik skalerer effektivt fra få transaktioner til tusinder, samtidig med at ydeevne og præsentation holdes ensartet.
graph LR
A[HTML-skabelon] --> B[JavaScript-klon]
B --> C[Udfyld med data]
C --> D[Tilføj til fragment]
D --> E[Batch indsætning til DOM]
subgraph "Ydeevnefordele"
F[Enkel DOM-opdatering]
G[Konsistent formatering]
H[Genanvendeligt mønster]
end
E --> F
E --> G
E --> H
flowchart LR
A[Transaktionsdata] --> B[HTML-skabelon]
B --> C[Klon skabelon]
C --> D[Udfyld med data]
D --> E[Tilføj til DOM]
E --> F[Gentag for hver transaktion]
Trin 1: Opret transaktionsskabelonen
Tilføj først en genanvendelig skabelon til transaktionsrækker i dit HTML <body>:
<template id="transaction">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</template>
Forståelse af HTML-skabeloner:
- Definerer strukturen for en enkelt tabelrække
- Forbliver usynlig indtil den klones og udfyldes med JavaScript
- Indeholder tre celler til dato, beskrivelse og beløb
- Giver et genanvendeligt mønster for ensartet formatering
Trin 2: Forbered din tabel til dynamisk indhold
Tilføj dernæst et id til tabelkroppen, så JavaScript let kan målrette den:
<tbody id="transactions"></tbody>
Hvad dette opnår:
- Opretter et klart mål for indsættelse af transaktionsrækker
- Adskiller tabelstruktur fra det dynamiske indhold
- Muliggør nem rydning og genopfyldning af transaktionsdata
Trin 3: Byg fabrikationsfunktionen for transaktionsrækker
Lav nu en funktion, der omdanner transaktionsdata til HTML-elementer:
function createTransactionRow(transaction) {
const template = document.getElementById('transaction');
const transactionRow = template.content.cloneNode(true);
const tr = transactionRow.querySelector('tr');
tr.children[0].textContent = transaction.date;
tr.children[1].textContent = transaction.object;
tr.children[2].textContent = transaction.amount.toFixed(2);
return transactionRow;
}
Opdeling af denne fabrikationsfunktion:
- Finder skabelonelementet via dets ID
- Kloner skabelonens indhold for sikker manipulation
- Vælger tabelrække-elementet i den klonede kopi
- Udfylder hver celle med transaktionsdata
- Formaterer beløbet til korrekt decimalvisning
- Returnerer den færdige række klar til indsættelse
Trin 4: Generer flere transaktionsrækker effektivt
Tilføj denne kode til din updateDashboard()-funktion for at vise alle transaktioner:
const transactionsRows = document.createDocumentFragment();
for (const transaction of account.transactions) {
const transactionRow = createTransactionRow(transaction);
transactionsRows.appendChild(transactionRow);
}
updateElement('transactions', transactionsRows);
Forståelse af denne effektive tilgang:
- Opretter en dokumentfragment til at samle DOM-operationer
- Går igennem alle transaktioner i kontodataene
- Genererer en række for hver transaktion ved hjælp af fabrikfunktionen
- Samler alle rækker i fragmentet, før de føjes til DOM
- Udfører én samlet DOM-opdatering i stedet for flere individuelle indsættelser
⚡ Ydeevneoptimering:
document.createDocumentFragment()fungerer som samleprocessen hos Boeing – komponenter klargøres uden for hovedlinjen og installeres derefter som en komplet enhed. Denne batch-tilgang minimerer DOM-omflytninger ved at udføre én enkelt indsættelse i stedet for flere individuelle operationer.
Trin 5: Forbedr opdateringsfunktionen til blandet indhold
Din updateElement() funktion håndterer i øjeblikket kun tekstindhold. Opdater den til at arbejde med både tekst og DOM-noder:
function updateElement(id, textOrNode) {
const element = document.getElementById(id);
element.textContent = ''; // Fjerner alle børn
element.append(textOrNode);
}
Nøgleforbedringer i denne opdatering:
- Rydder eksisterende indhold, før nyt indhold tilføjes
- Accepterer enten tekststrenge eller DOM-noder som parametre
- Bruger
append()metoden for fleksibilitet - Bevarer bagudkompatibilitet med eksisterende tekstbaseret brug
Tag dit dashboard på en prøvetur
Tid til sandhedens øjeblik! Lad os se dit dynamiske dashboard i aktion:
- Log ind med
testkontoen (den har eksempeldata klar) - Naviger til dit dashboard
- Tjek at transaktionsrækker vises med korrekt formatering
- Sørg for at datoer, beskrivelser og beløb alle ser rigtige ud
Hvis alt virker, burde du se en fuldt funktionel transaktionsliste på dit dashboard! 🎉
Det har du opnået:
- Bygget et dashboard, der kan håndtere enhver mængde data
- Oprettet genanvendelige skabeloner til ensartet formatering
- Implementeret effektive DOM-manipulationsteknikker
- Udviklet funktionalitet svarende til produktionsbankapplikationer
Du har med succes forvandlet en statisk webside til en dynamisk webapplikation.
🎯 Pædagogisk status: Dynamisk indholdsgenerering
Forståelse af arkitektur: Du har implementeret en sofistikeret data-til-UI-pipeline, som afspejler mønstre brugt i frameworks som React, Vue og Angular.
Nøglekoncepter mestret:
- Skabelonbaseret rendering: Oprettelse af genanvendelige UI-komponenter
- Dokumentfragmenter: Optimering af DOM-ydeevne
- Sikker DOM-manipulation: Undgåelse af sikkerhedsrisici
- Datatransformation: Omdannelse af serverdata til brugergrænseflader
Brancheforbindelse: Disse teknikker danner grundlaget for moderne frontend-frameworks. Reacts virtuelle DOM, Vues skabelonsystem og Angulars komponentarkitektur bygger alle oven på disse kernemekanismer.
Refleksionsspørgsmål: Hvordan ville du udvide dette system til at håndtere opdateringer i realtid (f.eks. nye transaktioner der automatisk dukker op)? Overvej WebSockets eller Server-Sent Events.
📈 Din tidslinje for datastyringsekspertise
timeline
title Data-Drevet Udviklingsrejse
section Fundamentopbygning
API Opsætning & Test
: Forstå klient-server kommunikation
: Mestre HTTP forespørgsels-/responscyklus
: Lær fejlfindingsmetoder
section Autentificeringsmestring
Async Funktion Mønstre
: Skriv ren async/await kode
: Håndter promises effektivt
: Implementer fejlgraenser
Bruger Session Håndtering
: Opret globale tilstands-mønstre
: Byg navigation guards
: Design brugerfeedback systemer
section Dynamisk UI Udvikling
Sikker DOM Manipulation
: Forebyg XSS sårbarheder
: Brug textContent fremfor innerHTML
: Skab tilgængelighedsvenlige grænseflader
Skabelonsystemer
: Byg genanvendelige UI komponenter
: Optimer ydeevne med fragmenter
: Skaler til at håndtere store datasæt
section Professionelle Mønstre
Produktionsklar Kode
: Implementer omfattende fejlhåndtering
: Følg sikkerhedens bedste praksis
: Skab vedligeholdelsesvenlige arkitekturer
Moderne Webstandarder
: Mestre Fetch API mønstre
: Forstå CORS konfigurationer
: Byg responsive, tilgængelige UIs
🎓 Afgangsmilepæl: Du har med succes bygget en komplet datadrevet webapplikation ved hjælp af moderne JavaScript-mønstre. Disse færdigheder kan direkte overføres til arbejde med frameworks som React, Vue eller Angular.
🔄 Næste niveau kompetencer:
- Klar til at udforske frontend-frameworks, der bygger på disse koncepter
- Forberedt på at implementere realtidsfunktioner med WebSockets
- Udstyret til at bygge Progressive Web Apps med offline kapabiliteter
- Fundamentet lagt for at lære avancerede state management-mønstre
GitHub Copilot Agent Udfordring 🚀
Brug Agent-tilstanden til at løse følgende udfordring:
Beskrivelse: Forbedr bankappen ved at implementere en søge- og filterfunktion, som gør det muligt for brugere at finde specifikke transaktioner via datointerval, beløb eller beskrivelsesord.
Prompt: Opret en søgefunktionalitet for bankappen, der inkluderer: 1) Et søgeformular med inputfelter til datointerval (fra/til), minimum/maximum beløb, og søgeord i transaktionsbeskrivelser, 2) En filterTransactions() funktion, der filtrerer account.transactions arrayet baseret på søgekriterierne, 3) Opdatering af updateDashboard() funktionen til at vise filtrerede resultater, og 4) Tilføj en "Ryd filtre" knap til at nulstille visningen. Brug moderne JavaScript array metoder som filter() og håndter kanttilfælde for tomme søgekriterier.
Læs mere om agent-tilstand her.
🚀 Udfordring
Klar til at tage din bankapp til næste niveau? Lad os få den til at se ud og føles som noget, du virkelig vil bruge. Her er nogle idéer til at starte din kreativitet:
Gør den smuk: Tilføj CSS-styling for at forvandle dit funktionelle dashboard til noget visuelt appellerende. Tænk rene linjer, god afstand og måske endda subtile animationer.
Gør den responsiv: Prøv at bruge media queries til at skabe et responsivt design, der fungerer godt på telefoner, tablets og desktops. Dine brugere vil takke dig!
Tilføj lidt flair: Overvej at farvekode transaktioner (grøn for indkomst, rød for udgifter), tilføje ikoner eller skabe hover-effekter der får interfacet til at føles interaktivt.
Sådan kunne et poleret dashboard se ud:
Føl dig ikke forpligtet til at matche det præcist – brug det som inspiration og gør det til dit eget!
Post-forelæsning quiz
Opgave
Refactor og kommenter din kode
Ansvarsfraskrivelse: Dette dokument er blevet oversat ved hjælp af AI-oversættelsestjenesten Co-op Translator. Selvom vi bestræber os på nøjagtighed, bedes du være opmærksom på, at automatiserede oversættelser kan indeholde fejl eller unøjagtigheder. Det originale dokument på dets oprindelige sprog bør betragtes som den autoritative kilde. For vigtig information anbefales professionel menneskelig oversættelse. Vi påtager os intet ansvar for misforståelser eller fejltolkninger, der opstår som følge af brugen af denne oversættelse.



