Angular Elements
For creating custom elements, angular elements now support content projection using web standards.
Example
<my-custom-element>This content can be projected!</my-custom-element>
The support for the official Shadow DOM specification improved for Angular Elements. In Angular 7, content can also project into an Angular Element from the outside. This is done via the Native API using <slot> elements.
Angular Elements
which are Angular components designed as web components that can
be used alone now in Angular version 7 supports content projection using web standards
for the custom HTML element
The introduction of the new standard HTML tag i.e <slot> is done by the Web Component Specification.
To perform content projection you can use ng-content, as shown in the listing below:
AppComponent.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-greet', template: ` <h2>{{title}}</h2> <ng-content></ng-content> ` }) export class AppComponent { title = 'Greet'; }
The problem faced with the above approach is that if you use AppComponent as an Angular Element then you will not be able to project content. To understand this in a better way, let us start by converting AppComponent to an Angular Element.
After converting AppComponent to an Angular Element, AppModule should look like the listing below:
AppComponent.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule, Injector } from '@angular/core'; import { AppComponent } from './app.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, BrowserAnimationsModule ], exports: [ BrowserAnimationsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { constructor(private injector: Injector) { const customElement = createCustomElement(AppComponent, { injector }); customElements.define('app-root', customElement); } ngDoBootstrap() { } }
Upon running application, you will find that <h2> element has not been projected to the Angular AppComponent.
After starting Angular 7
After releasing of Angular 7
, another option available to perform
content projection. For doing content projection in an Angular Element, you have
to do following:
- Set ViewEnacpsulation to ShadowDom.
- Use slot instead of <ng-content>
Let us modify AppComponent as shown in the listing below:
AppComponent.ts
import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'app-greet', template: ` <h2>{{title}}</h2> <slot name='message'></slot> `, encapsulation: ViewEncapsulation.ShadowDom }) export class AppComponent { title = 'Greet Component'; }
We have set the encapsulation
to ShadowDom
and replaced
<ng-content>
with <slot>
Angular has been supporting ShadowDom since its beginning. Until Angular 6.0
, there
were three-encapsulation modes:
- Emulated
- Native
- None
The Native mode was used to create ShadowDom V.0 and emulated was the default mode.
Starting with Angular 6.1
, Angular started supporting ShadowDom V.1, also. The fourth
option for the ShadowDom can be enabled by using ShadowDom V.1 on components. Angular
creates Shadow Dom V.1 if you set encapsulation to ShadowDom.You must have encapsulation
set to ShadowDom for doing content projection in an Angular Element.
Now, upon running the application, you will find the content has been projected as shown in the image below:
Therefore, you can project content
in Angular Element in Angular 7.0
by using ShadowDom
Encapsulation mode and slot.