Content Projection in Angular using ng-content

krishnapolanki

KrishnaSai Polanki

Posted on August 20, 2021

Content Projection in Angular using ng-content

In order to create the re-usable and flexible components content projection is a great option in Angular. Using ng-content we can do the content projection in Angular.

In general content projection means inserting or projecting some content from one component into another component. For example you want to insert some dynamic html element(s) into component(child component) when it is used inside a parent component.

Common implementation of content projection in Angular are

  • Single Slot Content Projection
  • Multi Slot Content Projection
  • Conditional Content Projection

Single Slot Content Projection:

Single slot content projection means there will be single source of the content which needs to project into component. Let's understand with an example.

child-component.html (selector: cp-child)

<h2>Single Slot Content Projection Example</h2>
<ng-content></ng-content>
<input type="text" />
<p>This is simple example to demonstrate the single slot content projection.</p>
Enter fullscreen mode Exit fullscreen mode

parent-component.html

<cp-single>
  <mat-icon>email</mat-icon>
</cp-single>
<cp-single>
  <mat-icon>home</mat-icon>
</cp-single>
Enter fullscreen mode Exit fullscreen mode

Here we can see the same component is reused by projecting different content, and the result will look like this

Single Slot Projectiont

Multi Slot Content Projection:

Let's if there is need of projecting multiple content in to the same component then we can achieve it with multi slot projection using the select attribute of the ng-content. Let's see how it works with an example.

child-component.html (selector: cp-child)

<h2>Multi Slot Content Projection Example</h2>
<ng-content select="[projected-label]"></ng-content>
<ng-content select="[projected-icon]"></ng-content>
<input matInput />
<ng-content select="[projected-hint-msg]"></ng-content>
<p>This is simple example to demonstrate the multi slot content projection.</p>
Enter fullscreen mode Exit fullscreen mode

parent-component.html

<cp-multi-slot>
  <mat-icon projected-icon>email</mat-icon>
  <mat-label projected-label>Enter Email</mat-label>
  <mat-hint projected-hint-msg>example@example.com</mat-hint>
</cp-multi-slot>
Enter fullscreen mode Exit fullscreen mode

Here we can see that each ng-content has select attribute with the name which matches with the projected content from the parent component.

Suppose if didn't mention the select attribute then the non-matching content will will projected into that placeholder.

This is how the multi-slot projection looks like.

Multi Slot Projection

Conditional Content Projection:

Let's say we have a situation where we need to project content based on certain condition then we can achieve it with conditional content projection.

But in such scenarios it is recommended to use the ng-template than the ng-content. The reason is Angular will always instantiate the content which is projecting even if the content is not rendered, but ng-template will instantiate only when the content is rendered.

ngProjectAs:

Suppose if there is a situation you want to project certain content which is part of another element say for example content inside the ng-container then we can make use of the attribute ngProjectAs. Let' see with an example

parent-component.html

<cp-multi-slot>
  <ng-container ngProjectAs="complex-ele">
    <h2>This the Demo of Complex content projection</h2>
    <p>Simple Demo of complex content projection using ngProjectAs</p>
  </ng-container>
  <div another-ele>
    <p>This is another element to project into component</p>
  </div>
</cp-multi-slot>
Enter fullscreen mode Exit fullscreen mode

component where the dynamic content projected

<p>Complex Multi-slot Projection</p>
<ng-content select="['complex-ele']"></ng-content>
<ng-content select="['another-ele']"></ng-content>
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
krishnapolanki
KrishnaSai Polanki

Posted on August 20, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related