S SvelteKurs
M4 · Template-Logik

{#if} & {#each} — Bedingungen und Schleifen

Logik im Markup: zeige Inhalte abhängig vom State an und rendere Listen — mit Index, Schlüssel und Fallback für leere Listen.

Bedingungen mit {#if}

In Svelte steuerst du sichtbare Inhalte direkt im Markup mit Logik-Blöcken. Ein Block beginnt mit {#…}, kann Zwischen-Zweige mit {:…} haben und endet mit {/…}. Für Bedingungen nutzt du {#if}:

svelte
{#if punkte >= 100}
  <p>🏆 Gewonnen!</p>
{:else if punkte >= 50}
  <p>Fast geschafft …</p>
{:else}
  <p>Weiter so!</p>
{/if}

{:else if} und {:else} sind optional — genau wie in jeder normalen if-Kette. Der Inhalt eines nicht zutreffenden Zweigs wird gar nicht ins DOM gerendert (nicht nur versteckt).

🛤️ Rails-Vergleich: ERB-Kontrollfluss

Das Prinzip kennst du aus ERB. Der große Unterschied: In Rails läuft die Logik einmal serverseitig beim Rendern. In Svelte ist sie reaktiv — ändert sich der State im Browser, wertet Svelte den Block automatisch neu aus und aktualisiert das DOM. Kein <% %> gegen <%= %>-Unterscheiden: In Svelte ist alles ein Ausdruck.

aufgaben/index.html.erb erb
<%# Rails/ERB: Bedingung und Schleife im View %>
<% if @aufgaben.any? %>
  <ul>
    <% @aufgaben.each_with_index do |aufgabe, i| %>
      <li><%= i + 1 %>. <%= aufgabe.text %></li>
    <% end %>
  </ul>
<% else %>
  <p>Keine Aufgaben.</p>
<% end %>

Listen mit {#each}

Mit {#each} rendest du eine Liste. In der einfachsten Form iterierst du über ein Array und bindest jedes Element an einen Namen:

svelte
{#each aufgaben as aufgabe}
  <li>{aufgabe.text}</li>
{/each}

Index als zweites Argument

Brauchst du die Position, gibst du nach dem Element einen Index-Namen an:

svelte
{#each aufgaben as aufgabe, i}
  <li>{i + 1}. {aufgabe.text}</li>
{/each}

Der Schlüssel (Key) — wichtig!

In runden Klammern gibst du einen eindeutigen Schlüssel pro Eintrag an. Damit weiß Svelte bei Änderungen der Liste, welches DOM-Element zu welchem Datensatz gehört — und kann gezielt einzelne Einträge aktualisieren, verschieben oder entfernen, statt die ganze Liste neu aufzubauen.

svelte
{#each aufgaben as aufgabe (aufgabe.id)}
  <li>{aufgabe.text}</li>
{/each}

⚠️ Fast immer einen Key setzen

Ohne Key arbeitet Svelte positionsbasiert. Fügst du dann vorne ein Element ein oder sortierst um, kann lokaler Zustand (Eingabefelder, laufende Transitions, Checkbox-Zustände) am „falschen" Eintrag hängen bleiben. Nutze eine stabile ID als Key — nicht den Index i, denn der verschiebt sich beim Umsortieren mit.

Destructuring direkt im each

Wie in normalem JavaScript kannst du das Element gleich zerlegen — das spart wiederholtes aufgabe.:

svelte
{#each aufgaben as { id, text, erledigt } (id)}
  <li class:done={erledigt}>{text}</li>
{/each}

Leere Listen mit {:else}

Ein {#each} darf einen {:else}-Zweig haben. Er wird gerendert, wenn die Liste leer ist — ideal für „Keine Einträge"-Hinweise:

svelte
{#each treffer as treffer (treffer.id)}
  <li>{treffer.name}</li>
{:else}
  <p>Keine Treffer gefunden.</p>
{/each}

Live ausprobieren

Die folgende Aufgabenliste kombiniert {#if} und {#each} mit echtem State dieser Seite. Der Filter „nur offene" schaltet ein $derived-Array um, und der leere Zustand nutzt {:else}:

▶ Aufgaben mit Filter · Interaktiv
2 von 3 offen
  • Svelte-Tutorial lesen
  • {#each} verstehen
  • Kaffee kochen

Hake alle Aufgaben ab, während „Nur offene zeigen" aktiv ist — dann greift der {:else}-Zweig.

Zusammenfassung

💡 Das Wichtigste

  • {#if} / {:else if} / {:else} steuern, was gerendert wird.
  • {#each liste as item, i (key)}: Element, optionaler Index, in Klammern der Schlüssel.
  • Setze fast immer einen stabilen Key (ID) — nicht den Index.
  • Destructuring (as { id, text }) funktioniert direkt im each.
  • {:else} im each rendert den Leer-Zustand.

🎯 Probier es selbst

Erweitere die Demo um ein Eingabefeld und einen Button, mit dem sich neue Aufgaben hinzufügen lassen (vergib eine neue eindeutige id). Ergänze außerdem einen zweiten Filter „nur erledigte" und beobachte, dass dank des Keys der lokale Checkbox-Zustand beim Umschalten korrekt bei den richtigen Einträgen bleibt.