Kartons mit verschiedenen Snacks, die auf einem Bürgersteig neben einem geparkten Motorroller gestapelt sind.

Angular-Komponenten haben immer ein Host-Element. Das ist ein Pseudo-HTML-Tag mit dem Selektor-Name der Komponente. Dieses Host-Element ist insbesondere bei Listen problematisch für die Semantik des HTML. Eine Anleitung zur Sicherstellung von semantisch korrekt verpacktem HTML.

Host-Element als Pseudo-HTML-Tag

Wenn Sie eine Angular-Komponente einbinden, wird diese im generierten HTML in einem Host-Element aufgeführt. Dieses Host-Element fungiert als Klammer um das komponentenspezifische HTML und trägt die Bezeichnung, welche als Selektor festgelegt wurde.

Eine Komponente hat einen bestimmten Selektor, der im @Component-Dekorator angegeben wird:

@Component({
  selector: 'test-name',
  template: '<div>Dummy content</div>', 
  styleUrls: [ './test-name.component.scss']
})
exportclassTestNameComponent{ … }

Wenn die Komponente z.B. direkt im HTML der AppComponent eingebunden wird, wird dafür ein Pseudo-HTML-Tag mit dem Selektor der Komponente eingesetzt:

<test-name></test-name>

Dieses Pseudo-HTML-Tag ist dann auch im HTML der Applikation so ersichtlich:

<app-root>
  …
  <test-name>
     <div>Dummy content</div>
  </test-name>
  …
</app-root>

Dieses zusätzliche HTML-Element können Sie mit CSS-Styles ergänzen (im CSS/SCSS der Komponente):

:host {
  display: block
}

Host-Element und semantisches HTML

Diese Angular-Eigenheit verursacht meist keine Schwierigkeiten, da die Browser mit diesen Pseudo-HTML-Tags umgehen können und da Sie diese Elemente auch mit Stilregeln ergänzen können. Es gibt aber Fälle, in denen die Semantik des HTMLs durch dieses Host-Element beeinträchtigt wird, wenn keine entsprechende Vermeidungsmassnahme ergriffen wird.

Listen stellen ein Beispiel für den etwas umständlichen Umgang mit diesen Host-Elementen dar. Um ein semantisch stimmiges HTML zu erhalten, führen Sie die Listen-Tags (<li>) direkt innerhalb der Listen-Tags (<ul>, <ol>) auf.

Sollen die Liste und die Listen-Elemente wiederverwertbar sein, bietet es sich an, für beide eine Komponente zu erstellen (z.B. ListComponent, ListItemComponent). Damit die ListComponent flexibel befüllt werden kann, nehmen Sie sinnvollerweise nur das Listen-Tag und einen Füllbereich (ng-content) hinein:

<!-- list-component.component.html -->
<ul>
  <ng-content><!-- list content goes here --></ng-content>
</ul>

In der AppComponent (oder an anderer Stelle) wird dann die Liste mit den beiden Komponenten zusammengebaut , z.B. unter Verwendung einer «For»-Schlaufe im Template:

<list>
  <list-item *ngFor="let item of items"></list-item>
</list>

Das generierte HTML führt dann jeweils innerhalb des ul-Tags zuerst das Host-Element der Listen-Elemente anstelle des li-Tags auf:

<list>
  <ul>
     <list-item>
        <li>…</li>
     </list-item>
  <ul>
</list>

Um aber sicherzustellen, dass direkt innerhalb eines ul-Tags nur li-Tags vorhanden sind, nehmen Sie entsprechend das li-Tag aus der ListItemComponent heraus. An jeder Stelle, an der die ListComponent verwendet wird, müsste also folgendes gemacht werden:

<list>
  <li *ngFor="let item ofitems">
     <list-item></list-item>
  </li>
</list>

Das li-Tag ist nun aber weder Teil der List- noch der ListItemComponent. Trotzdem können Sie über «ng-deep» mit Stilregeln ergänzen (im CSS der ListComponent), wobei «ng-deep» aber als veraltet gilt (siehe Angular Guide: Component Styles):

ul::ng-deep> li {
  border-bottom: 1px solid black;
}

Konklusion

Host-Elemente sind meist unproblematisch, können aber bei falscher Verwendung die HTML-Semantik gefährden. Der beschriebene Weg für die Darstellung von Listen mag zwar etwas unschön sein, aber Sie halten so die Semantik ein, da das benötigte li-Tag weder der List- noch der ListItemComponent zugehörig ist.

Dieser Artikel ist Teil unserer Serie über Stärken und Schwächen von Angular.

Und wie wird mein nächstes Angular Projekt zum Erfolg? Mit Zeix.

fallback image

Während der Programmierung dauernd umkonzipieren oder gar Code wegwerfen? Nicht mit uns – wir bringen Ihre Anwendung performant, stabil und ohne unnötige Umwege ans Ziel.