Angular

Lab 2: Control Flow

arrow_back Alle labs
timer 20 minutter
sell module-2-start → module-3-start
Mål: Opret en HerdCard component, byg et data array med en interface, og brug @for til at rendere kort dynamisk. Forstå track og @empty.

Udgangspunkt

Checkout tag module-2-start. Alle kort er hardcoded direkte i herd-input.html. Du har 6 næsten identiske blokke HTML.

git checkout module-2-start

Trin for trin

looks_one Generér HerdCard component

ng generate component calculator/herd-card

looks_two Flyt ét kort til HerdCard

Kopiér HTML for ét enkelt kort (f.eks. Malkekøer) fra herd-input.html til herd-card.html:

<!-- herd-card.html -->
<div class="card active">
  <span class="badge">AKTIV</span>
  <div class="card-top">
    <span class="emoji">🐄</span>
    <div class="factor">
      <span>CO2e/år</span>
      <span>3.000 kg</span>
    </div>
  </div>
  <h3>Malkekøer</h3>
  <div class="input-wrap">
    <input type="number" value="150" class="has-value" min="0" placeholder="0" />
    <span class="suffix">stk.</span>
  </div>
</div>

Flyt også de tilhørende card styles fra herd-input.css til herd-card.css (husk ViewEncapsulation fra Lab 1!).

looks_3 Opret data array med interface

I herd-input.ts, definér en Card interface og et array med alle dyretyper:

// herd-input.ts
import { Component } from '@angular/core';
import { HerdCard } from '../herd-card/herd-card';

interface HerdCounts {
  dairyCows: number;
  beefCows: number;
  calves: number;
  pigs: number;
  sows: number;
  chickens: number;
}

interface Card {
  key: keyof HerdCounts;
  label: string;
  emoji: string;
  factor: number;
}

@Component({
  selector: 'app-herd-input',
  imports: [HerdCard],
  templateUrl: './herd-input.html',
  styleUrl: './herd-input.css',
})
export class HerdInput {
  readonly herdCards: Card[] = [
    { key: 'dairyCows', label: 'Malkekøer', emoji: '🐄', factor: 3000 },
    { key: 'beefCows', label: 'Kødkvæg', emoji: '🐂', factor: 2400 },
    { key: 'calves', label: 'Kalve & Ungdyr', emoji: '🐃', factor: 1000 },
    { key: 'pigs', label: 'Slagtesvin', emoji: '🐖', factor: 50 },
    { key: 'sows', label: 'Søer', emoji: '🐗', factor: 450 },
    { key: 'chickens', label: 'Slagtekyllinger', emoji: '🐓', factor: 1.5 },
  ];
}
lightbulb
Tip: Start med et tomt array (herdCards: Card[] = []) og se hvad der sker i browseren. Tilføj så objekterne ét ad gangen.

looks_4 Brug @for i herd-input.html

Erstat alle de hardcoded kort med en @for loop:

<!-- herd-input.html -->
<div class="grid">
  @for(herd of herdCards; track herd.key) {
    <app-herd-card />
  } @empty {
    <p>Ingen dyrekategorier tilgængelige.</p>
  }
</div>

track herd.key fortæller Angular hvordan den identificerer hvert element. Det er påkrævet for at Angular kan optimere DOM opdateringer.

@empty blokken vises når arrayet er tomt. Prøv at sætte herdCards = [] og se den i aktion!

looks_5 Verificér resultatet

I browseren bør du nu se 6 kort i grid layoutet. De er alle identiske (hardcoded Malkekøer) fordi HerdCard endnu ikke modtager data via @Input(). Det fikser vi i Lab 3.

Hint: Komplet herd-input.html
<!-- herd-input.html -->
<div class="container">
  <div class="herd-header">
    <h2>
      <span class="material-symbols-outlined">grid_view</span>
      Din Besætning
    </h2>
    <button class="reset-btn">
      <span class="material-symbols-outlined">restart_alt</span> Nulstil
    </button>
  </div>

  <p class="subtitle">Klik på en kategori ...</p>

  <div class="grid">
    @for(herd of herdCards; track herd.key) {
      <app-herd-card />
    }
  </div>
</div>

Dokumentation