Jede Angular-Komponente benötigt einen CSS-Selektor. Dieser definiert, durch welches HTML-Element oder welches Attribut die Komponente in Vorlagen eingebunden und instanziiert wird. Die Wahl des richtigen Selektors ist entscheidend, um den Code semantisch sauber, fehlerfrei und gut nutzbar für andere Entwickler zu halten. In diesem Artikel schauen wir uns die verschiedenen Arten von Selektoren und empfohlene Namenskonventionen (Präfixe) an.
Grundlagen des Selektors
Angular nutzt den Selektor zur Kompilierzeit (Compile-Time), um statisch zu bestimmen, an welcher Stelle im HTML-Template eine Komponente erzeugt werden soll. Jedes Element im DOM darf dabei immer nur von genau einer Komponente kontrolliert werden. Gibt es mehrere Komponenten-Selektoren, die auf dasselbe Element zutreffen, wirft Angular einen Fehler.
import { Component } from '@angular/core';
@Component({
selector: 'app-profile-photo',
template: `<img src="profile-photo.jpg" alt="Your profile photo" />`,
standalone: true
})
export class ProfilePhotoComponent {}Dieser wird dann in einem anderen Template aufgerufen:
<!-- Die ProfilePhotoComponent wird hier gerendert -->
<app-profile-photo></app-profile-photo>Unterstützte Selektor-Arten
Angular unterstützt nicht jeden beliebigen CSS-Selektor (wie Kind-Kombinatoren >, oder Nachfahren-Kombinatoren). Es wird ein bestimmtes Set an elementaren CSS-Selektoren erlaubt:
1. Tag-Selektor (Custom Elements)
Dies ist der häufigste Selektor. Die Komponente wird als eigenes HTML-Element (Tag) verwendet. Er sollte laut W3C-Standard immer einen Bindestrich (-) enthalten, z.B. app-button.
@Component({
selector: 'youtube-player',
/* ... /
})
export class YoutubePlayerComponent { }2. Attribut-Selektor
Anstatt ein neues HTML-Tag zu erschaffen, wird die Komponente an ein native HTML-Tag gebunden, indem ein bestimmtes Attribut verwendet wird. Dies ist extrem nützlich, wenn du native Funktionalitäten (z. B. von <button>, <a> oder <table>) behalten möchtest, wie Keyboard-Fokus oder ARIA-Attribute.
@Component({
selector: 'button[yt-upload]',
/ ... /
})
export class YouTubeUploadButton { }Die Nutzung im Template sieht dann so aus:
<button yt-upload>Neues Video hochladen</button>3. Exakter Attribut-Wert (=)
Du kannst den Selektor so einschränken, dass ein Attribut einen ganz bestimmten Wert haben muss:
@Component({
selector: 'input[type="reset"]',
/ ... */
})
export class ResetInputComponent { }4. Kombinieren und :not Pseudo-Klasse
Du kannst Selektoren wie in CSS aneinanderhängen (für UND) oder durch Kommata trennen (für ODER). Außerdem wird die :not() Pseudo-Klasse unterstützt, um Elemente auszuschließen:
@Component({
// Trifft auf Elemente mit Attribut [dropzone] zu, die KEIN textarea sind
selector: '[dropzone]:not(textarea)',
/* ... /
})
export class DropZoneComponent { }
@Component({
// Trifft auf <drop-zone> Tags ODER auf Elemente mit [dropzone] Attribut zu
selector: 'drop-zone, [dropzone]',
/ ... */
})
export class AlternativeDropZoneComponent { }Präfixe und Namenskonventionen
Um Kollisionen mit zukünftigen nativen HTML-Tags oder Drittanbieter-Bibliotheken zu vermeiden, sollten Selektoren immer ein Präfix haben.
Die Angular CLI nutzt standardmäßig das Präfix app- (z. B. app-header). Wenn du an einer größeren Anwendung, einem Design-System oder einer Bibliothek arbeitest, solltest du ein spezifisches, konsistentes Präfix für dein Projekt verwenden (z. B. yt- für YouTube, mat- für Angular Material).
Häufige Stolperfallen
Komponente wird nicht gerendert bei Attribut-Selektoren
Wenn du eine Komponente als Tag einbindest (z. B. <yt-player>), warnt Angular, falls es diesen Tag nicht kennt. Nutzt du aber einen Attribut-Selektor (<button yt-upload>) und vergisst, die Komponente im imports-Array der Parent-Komponente zu deklarieren, rendert der Browser einfach einen normalen Button, ohne dass Angular einen Fehler ausgibt!
DOM zur Laufzeit ändern
Angular matcht Selektoren nur zur Kompilierzeit der Templates. Fügst du HTML-Strings per JavaScript innerHTML oder DOM-APIs in die Seite ein, werden darin enthaltene Angular-Selektoren nicht erkannt oder instanziiert.
Groß-/Kleinschreibung
Selektoren sind in Angular (wie auch in nativem HTML für Custom Elements) strikt “case-sensitive” bzw. sollten komplett in Kleinbuchstaben mit Bindestrichen (kebab-case) geschrieben werden.