top of page

Content Projection : How to project content using ng-content tag?

Content projection is a pattern in which you insert, or project, the content you want to use inside another component. For example, you could have a Card component that accepts content provided by another component.


How to project content using ng-content tag?

Let’s say we have a component that represents a progress bar, and we would like to allow the insertion of a progress bar description within it using content projection.


We will need to add a ng-content tag within the progress bar component where we want the progress bar description to appear:

<div class="progress-wrapper">
    <div class="progress-track"></div>
    <div
        [ngStyle]="{ 
            background: progressColor, 
            width: '60%' }"
        class="progress-color-line">
    <ng-content></ng-content>
    <!--here the progress description will appear-->
</div>
</div>

Now we’ll add the HTML we want to display instead of the ng-content tag inside the progress bar component tag:

<h1>Single Ng Content example</h1>

<shared-progress-bar[progressValue]="'60%'"[progressColor]="'green'">
    <div>Today Sales</div>
</shared-progress-bar>

As a result will be displayed on the screen:

Now the developer / component can add whatever content they want, And it will be projected to the component instead of the ng-content tag, Making our progress bar component more flexible.


How to project multiple contents using ng-content tag and the select directive

Now our progress bar component has become a bit more flexible, But what if we want in somewhere else in our app for any reason, to display the progress bar description text above the progress bar, And not inside it?


To make this happen we will need to design the component with multiple ng-content tags. And in order for the component to know in which ng-content tag to display the description of the progress bar, We will use the select directive.


Now if we want to allow any information to be displayed above the progress bar, we will need to create a ng-content tag above the progress bar, with a select directive that accepts any css selector you want, I used an attribute called project-on-top.


So now the progress bar component will look like this:

<ng-content select="[project-on-top]"></ng-content>
<!--here will be rendered all the content that got the project-on-top attribute-->
    <div class="progress-wrapper">
    <div class="progress-track"></div>
    <div
        [ngStyle]="
        { 
            background: progressColor, 
            width: progressValue }"
        class="progress-color-line">
    <ng-content></ng-content>
    <!--here will be rendered all the content that not have the 
    project-on-top attribute-->
    </div>
</div>

And the component that consumes the component of the progress bar will look like this:

<h1> Multiple Ng Contente xample</h1>

<shared-progress-bar[progressValue]="'60%'"[progressColor]="'green'">
    <div project-on-top>Today Sales on top</div>
</shared-progress-bar>

As a result will be displayed on the screen:


Now anywhere in our app, when we want to display the progress bar description above the progress bar we will use the project-on-top attribute on the element within the component’s tags.


And if we want to display the progress bar description within the progress bar, we don’t specify the project-on-top attribute on the element within the component’s tags.



Resource: Medium(Or Anaki), Angular


The Tech Platform

0 comments
bottom of page