Content Projection with Slots in Angular Elements (>=7)



 

Big thanks to Rob Wormald -- the mastermind behind Angular Elements in the Angular Team -- for reviewing this article.


Since Angular 7, we can use slots to project markup into an component's template. These slots have been introduced with Shadow DOM v1 which Angular supports since version 6.1.

This article shows how to use both, Shadow DOM v1 and slots. For this, it uses a component that shows a diagram:

Sample component

The title, as well as the description and the legend on the bottom can be adjusted using content projection with slots. You can find the source code in my GitHub repo (branch: ng7):

» Source Code (branch: ng7)

If this is interesting for you, you might also find our Angular Workshop for Enterprise Architectures of value.

Shadow DOM v1

Shadow DOM has always been an central concept for Angular Components. By default, Angular emulates this standard which isolates a component's style from other components. The idea is that one component's local styles shall not interfere with other components.

It's also possible to turn it off or to tell Angular to rely on the Browser's implementation which can provide a better isolation than the emulated one.

However, until Angular 6.1, Angular supported what's known as Shadow DOM v0. Meanwhile, browser vendors agreed on the revised Version 1 which will be widely implemented. At the time of writing, Chrome, Safari, Firefox and Opera already supported it and the Edge-team was currently implementing it.

To use Shadow DOM v1 in Angular (>= 6.1), just set the encapsulation property in the Component decorator to the newly introduced value ShadowDom:

@Component({ selector: 'app-dashboard-tile', templateUrl: './dashboard-tile.component.html', encapsulation: ViewEncapsulation.ShadowDom }) export class DashboardTileComponent implements OnInit { @Input() a: number; @Input() b: number; @Input() c: number; […] }

Don't confuse ViewEncapsulation.ShadowDom with ViewEncapsulation.Native which exists since Angular's first days and leverages Shadow DOM v0.

Slots for Content Projection

Many Web Components -- or to be more precise, many Custom Elements -- need to be adaptable with some markup passed as the element's content. This is also called content projected because the passed content is projected to different positions of the element's template.

For this, Shadow DOM v1 introduces the slot element. Each slot marks a position within a template where content can be projected to:

<div class="card"> <div class="header"> <h1 class="title"><slot name="title">Standardwert</slot></h1> </div> <div class="content"> <div style="height:200px"> <ngx-charts-pie-chart [labels]="true" [results]="data"> </ngx-charts-pie-chart> </div> <p><slot>Standardwert</slot></p> <i><slot name="legend">Standardwert</slot></i> </div> </div>

Between the opening and the closing slot tags, we can place some default markup that is shown if the caller does not pass any content for it. There can be one default slot and named ones.

When calling such a Custom Element, we can use the slot attribute to point to one of the named slots within the component's template:

<div class="col-sm-3"> <dashboard-tile a="10" b="5" c="15"> <span slot="title">Important Stuff</span> <span slot="legend">A, B and C show the values of A, B and C.</span> Only believe in statistics you've faked yourself. </dashboard-tile> </div>

Everything you connect to a slot that way will be projected to it. The rest is put into the default slot.

Accessing Projected Content

For accessing projected content, Angular provides hooks like ngAfterContentChecked or ngAfterContentInit as well as content queries using @ViewChild and @ViewChildren.

Unfortunately, they don't work with slots. But we can make use of the slotschange event instead:

<i><slot (slotchange)="slotChange($event)" name="legend">No Legend available.</slot></i>

In the set up event handler, we can grab the projected elements:

@Component({ [...] encapsulation: ViewEncapsulation.ShadowDom }) export class DashboardTileComponent implements OnInit { slotChange($event) { const assigned = $event.target.assignedNodes(); if (assigned.length > 0) { console.debug('shotchange', assigned[0]); } } }

 

 
Hier können Sie eine Anfrage für eine unverbindliche Schulung ode Beratung bzw. einen Workshop erstellen.
 
Unverbindliche Anfrage
 
 

Schulungen

Angular Schulung: Strukturierte Einführung

Lernen Sie in dieser interaktiven Schulung anhand einer Beispielanwendung den Einsatz von Angular für Ihre erfolgreichen Projekte kennen. Sie durchdringen die Hintergründe und bauen von der ersten Minute an auf Best Practices auf.

Details

Advanced Angular: Enterprise-Anwendungen und Architektur

In dieser Schulung erfahren Sie alles für die Entwicklung großer Anwendungen mit Angular: Mono-Repos, Micro-Apps, State Management, Performance und mehr

Details

Angular: Strukturierte Einführung

Seit der Ankündigung von Angular (2+) fragen sich Entwicklungs-Teams, welche Migrationspfade für AngularJS-1.x-Anwendungen vorliegen werden. Das im Lieferumfang von Angular enthaltene ngUpgrade bietet eine Antwort darauf. Es erlaubt einen Parallelbetrieb von AngularJS 1.x und Angular (2+) und stellt somit die Grundlage für eine schrittweise Migration dar.

Details

Progressive Web-Apps mit Angular

Progressive Web Apps bieten den Komfort nativer Anwendungen, indem sie auf moderne Browser APIs, wie Service Worker, setzen. Sie sind installierbar sowie offlinefähig und nutzen Hintergrundprozesse für Datensynchronisation und Push-Notifications. Diese Schulung zeigt anhand eines durchgehenden Beispiels was sich genau hinter diesem neuen Konzept verbirgt, wie solche Anwendungen mit Angular entwickelt werden und wie Sie in Ihren Projekten von den dahinterstehenden Ideen profitieren.

Details

Reaktive Architekturen mit Angular und Redux

Dieses interaktive Seminar vermittelt, wie Sie reaktive Anwendungen mit Angular entwickeln können.

Details

TypeScript

TypeScript gibt Ihnen alle Möglichkeiten der neuen JavaScript-Standards und zusätzlich ein statisches Typsystem, das dabei hilft, Fehler möglichst früh zu erkennen. Außerdem ist TypeScript die Grundlage für Angular. In diesem interaktiven Seminar lernen Sie diese mächtige Sprache anhand einer Fallstudie kennen.

Details

Weitere Schulungen ...