Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Simplifying Content Projection in Angular

DZone's Guide to

Simplifying Content Projection in Angular

In this post, we take a look at what 'content projection' is in Angular, how to demystify it, and how you can make use of it by way of an example.

· Web Dev Zone
Free Resource

Add user login and MFA to your next project in minutes. Create a free Okta developer account, drop in one of our SDKs to your application and get back to building.

In Angular, content projection is used to project content in a component. Let’s take a closer look at how it works:

Content projection allows you to insert a shadow DOM in your component. To put it simply, if you want to insert HTML elements or other components in a component, then you do that using the concept of content projection. In Angular, you achieve content projection using < ng-content >< /ng-content >.  You can make reusable components and scalable applications by properly using content projection.

To understand content projection, let us consider GreetComponent as shown in the code listing below: 

import { Component } from '@angular/core';

@Component({
    selector: 'greet',
    template: `{{message}}`
})
export class GreetComponent {

    message: string = "Hello There !"

}

Now if you use GreetComponent in another component, and want to pass a greeting message from the parent component, then you should use the @Input() decorator. This way, a modified GreetComponnet will look like the listing below:

import { Component, Input } from '@angular/core';

@Component({
    selector: 'greet',
    template: `{{message}}`
})
export class GreetComponent {

    @Input() message: string;

}

Using the @Input() decorator, you can pass a simple string to the GreetComponnet, but what if you need to pass different types of data to the GreetComponent such as:

  1. Inner HTML
  2. HTML Elements
  3. Styled HTML
  4. Another Component, etc.

To pass or project styled HTML or another component, content projection is used. Let us modify the GreetComponent to use content projection in this code: 

We are using this to project content in the GreetComponent. When you use the GreetComponent, you’ll pass content as shown below:

In the listing above, you are projecting styled HTML to the GreetComponent and you’ll get the following output:

This is an example of Single Slot Content Projection. Whatever you pass to the GreetComponent will be projected. So, let us pass more than one HTML element to the GreetComponent as shown in the listing below:

Here we are passing three HTML elements to the GreetComponent, and all of them will be projected. You will get the output as shown in the image below:

In the DOM, you can see that inside the GreetComponent, all HTML elements are projected. 

You may have a requirement to project elements in multiple slots of the component. In this next example, let’s say you want to create a greeting card like this:

This can be created using the component as shown below:

Let us say we have a requirement to pass the header element and a button element so the name and button can be dynamically passed to the GreetComponent.  This time, we need two slots:

  1. A slot for the header element
  2. A slot for the button element

Let’s modify the GreetComponent to cater to the above requirement as shown in the image below:

Here we’re using ng-content two times. Now, the question is, do we select a particular ng-content to project the h1 element and another ng-content to project a button element?

You can select a particular slot for projection using the <ng-content> selector. There are four types of selectors:

  1. Project using tag selector.
  2. Project using class selector.
  3. Project using id selector.
  4. Project using attribute selector. 

You can use the tag selector for multi-slot projection as shown in the listing below:

Next, you can project content to the GreetComponent as shown in the listing below:

As you can see, we are using the GreetComponent twice and projecting different h1 and button elements. You’ll get the output as shown in the image below:

The problem with using tag selectors is that all h1 elements will get projected to the GreetComponent. In many scenarios, you may not want that and can use other selectors such as a class selector or an attribute selector, as shown in the listing below:

Next, you can project content to the GreetComponent as shown in the listing below:

You’ll get the same output as above, however this time you are using the class name and attribute to project the content. When you inspect an element on the DOM, you will find the attribute name and the class name of the projected element as shown in the image below: 

Content projection is very useful to insert shadow DOM in your components. To insert HTML elements or other components in a component, you need to use content projection. In AngularJS 1.X, content projection was achieved using Transclusion, however, in Angular, it is achieved using <ng-content>.

In the next post, you will learn about more important concepts in Angular, so stay tuned.

Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

Topics:
shadow dom ,dom ,angular ,javascript ,web dev

Published at DZone with permission of Dhananjay Kumar, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}