Angular

Content Projection in Angular with Ng-Content

How often has it happened to you that while passing in dynamic content from parent to child, you have to use unnecessary...

Written by Luci · 2 min read >

How often has it happened to you that while passing in dynamic content from parent to child, you have to use unnecessary Input Property, and then there is the pain to send in a string in the Property binding to complete the requirement? Tough, right? This solution is quite straightforward but it is not the best practice to be followed and also has some shortcomings.

Today, we will see how the same requirement can be accomplished in a better way.

First, let’s see the problem statement if you have not understood the above.

Take a look at the example below:

export class AppComponent {
  passToChildren: string = 'This is using Input Decorator';
}

Here, in our app.component, we have declared a string and then utilized the same to pass value to the child component as:

<app-comp-a [dynamicContent]="passToChildren"></app-comp-a>

Here, dynamicContent is an Input decorator , which is then declared in the child component as:

export class CompAComponent implements OnInit {
@Input() dynamicContent: string;
constructor() {}
ngOnInit(): void {}
}

And the same is utilized in HTML as:

<p>comp-a works!</p>
<p>{{dynamicContent}}</p>

And we get the expected output as:

Without Content Projection

Easy, right?

But this approach has certain caveats:

1. As is evident from the template (HTML) of the child component, we are bounded to use the <p> tag there. Let’s suppose some other component uses the same child component and needs to show different content in span — then it becomes a sort of overhead.

One side note here, if you are thinking of passing in complete HTML through the Input decorator, then, unfortunately, it is not supported by the Input decorator.

2. If we have to pass in multiple string values, which are needed to display on HTML, then the number of Input properties will keep on increasing.

The solution for the above-mentioned problem is Content Projection, i.e., we will project or send in the complete content from the parent and the same can be displayed in the child using the ng-content directive.

Let’s see the same with an example.

We will change our app.component.html as:

<app-comp-a>
<p>This is using Content Projection</p>
</app-comp-a>

Here, instead of sending in an Input Property, we have sent in a complete HTML tag which we need to display in the child component.

To display the same in child the component, we will use the <ng-content> directive as shown below:

<p>comp-a works!</p>
<ng-content></ng-content>
<p>After Ng Content</p>

ng-content will act as a placeholder wherein the projected content will be displayed as:

The above is an example of Single Slot Content Projection wherein we have sent in a single tag.

Same way, multiple HTML tags can be sent from the parent to the child and can be rendered.

Let’s see how the same can be achieved.

We have changed app.component.html to:

<app-comp-a>
<span id="multiSlotId">
This is the new content to be projected based on id.
</span>
<p>This is using Content Projection</p>
<span class="multiSlotClass">
This is the new content to be projected based on class.
</span>
</app-comp-a>

Here, we have added a span with id attribute and another with class attribute. Basically, these help in identifying the place where they need to be rendered in the child component.

The child component will look like:

<ng-content select="#multiSlotId"></ng-content>
<p>comp-a works!</p>
<ng-content></ng-content>
<p>After Ng Content</p>
<ng-content select=".multiSlotClass"></ng-content>

ng-content is used with select attribute and within that will use name as used in CSS selector to set the placeholder with relevant identifier.

So, this in nutshell is all about how content projection can be used in Angular.

Written by Luci
I am a multidisciplinary designer and developer with a main focus on Digital Design and Branding, located in Cluj Napoca, Romania. Profile

Angular Basics: The CLI and Components

Luci in Angular
  ·   7 min read
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x