How we use it ?

Single-Slot

Basically you just add <ng-content></ng-content> in your html and this will replaced with content from outside the component

<!-- inside container component -->

<ng-content></ng-content> <!-- inside another component -->

<container-component> <p>Content Here</p> </container-component>

Multi-slot ( Targeted projection )

ng-content accepts a select attribute, which allow us to set specific css selector name for that slot.

Using element(s) name

<!-- inside container component -->

<ng-content select="slot-one"></ng-content> <!-- inside another component using container component -->

<container-component>

<slot-one>Content For Slot one</slot-one>

</container-component>

If you using it in a normal angular cli setup, you will hit an error if you use the <slot-one> tag now.

Unhandled Promise rejection: Template parse errors: ‘slot-one’ is not a known element, Angular does not recognize the slot-one tag. slot-one is neither a directive nor a component.

A quick way to get around this error is to add schema metadata property in your module, set value to NO_ERRORS_SCHEMA in your module file.

// app.module.ts import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; //

import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component';

import { ContainerComponent } from './container-component'; @NgModule({

imports: [BrowserModule],

declarations: [AppComponent, ContainerComponent],

bootstrap: [AppComponent],

schemas: [NO_ERRORS_SCHEMA] // add this line

})

export class AppModule {}

Using Attribute(s) [name] | [name][another-name]

<!-- inside container component -->

<!-- Using Single Attribute -->

<ng-content select="[slot-one]"></ng-content>

<!-- Using Multiple Attributes -->

<ng-content select="[slot][two]"></ng-content> <!-- inside another component using container component -->

<container-component>

<p slot-one>Content For Slot one</p>

<p slot two>Content For Slot two</p>

</container-component>

Using Attribute with Value [name="vlue"]

<!-- inside container component -->

<ng-content select="[slot='one']"></ng-content>

<ng-content select="[slot='two']"></ng-content> <!-- inside another component using container component -->

<container-component>

<p slot="one">Content For Slot one</p>

<p slot="two">Content For Slot two</p>

</container-component>

Using class(s) .name | .name.another-name

<!-- inside container component -->

<!-- Using Single Class -->

<ng-content select=".slot-one"></ng-content>

<!-- Using Multi Class -->

<ng-content select=".slot.two"></ng-content> <!-- inside another component using container component -->

<container-component>

<p class="slot-one">Content For Slot one</p>

</container-component>

Without using wrapping div

as you can see in the previous example you can use the target slot by wrapping your content with div or element and attach the selector with it, but in some cass you just want to put it there.

Using ngProjectAs angular attribute on ng-container tag or and tag you want.

<!-- inside container component -->

<!-- Element -->

<ng-content select="slot-one"></ng-content>

<!-- Attributes -->

<ng-content select="[slot-one]"></ng-content>

<ng-content select="[slot][two]"></ng-content>

<!-- Attributes with Value -->

<ng-content select="[slot='one']"></ng-content>

<ng-content select="[slot='two']"></ng-content> <!-- Inside ngProjectAs use projected name-->

<ng-container ngProjectAs="slot-one">

Very <strong>important</strong> text with tags.

</ng-container>

<ng-container ngProjectAs="[slot][two]">

Very <strong>important</strong> text with tags.

</ng-container>

Inside *ngFor