Harnessing the Power of ng-template for Flexible UI

Adebayo Oluwatobiloba
4 min readMay 28, 2023

--

Angular provides developers with a powerful tool called ng-template. This directive enables the creation of reusable templates that can be dynamically rendered, manipulated, and shared across multiple components. In this article, we’ll explore ng-template’s versatility and demonstrate its usage through practical examples.

Understanding ng-template

The ng-template directive in Angular allows us to define templates that are not immediately rendered. Instead, we can use them dynamically based on conditions or loop through them using directives like ngIf or ngFor. This separation of concerns helps keep our code modular and maintainable.

Basic Usage of ng-template

Let’s start with a simple example of using ng-template for conditional rendering.

<ng-template #conditionTemplate>
<p>This content is rendered conditionally.</p>
</ng-template>

<div *ngIf="condition; then conditionTemplate"></div>

In the above example, we define an ng-template with the reference name #conditionTemplate. We use the *ngIf directive to conditionally render the template based on the value of the condition variable.

ng-template with ngFor

Next, let’s explore how ng-template can be used with ngFor to generate dynamic lists.

<ng-template #listItemTemplate let-item>
<li>{{ item }}</li>
</ng-template>

<ul>
<ng-container *ngFor="let item of items">
<ng-container *ngTemplateOutlet="listItemTemplate; context: { $implicit: item }"></ng-container>
</ng-container>
</ul>

In this example, we define an ng-template with the reference name #listItemTemplate that represents a single list item. We then use ngFor to iterate over an array of items and use ngTemplateOutlet to render the template for each item.

Note that the $implicit keyword is used to define the default context variable inside an ng-template when using the ngTemplateOutlet directive. It allows you to assign a value to a template variable without explicitly naming it. For example

<ng-template let-item let-index="index">
<div>{{ index }}: {{ item }}</div>
</ng-template>

<div *ngFor="let item of items; index as i">
<ng-container *ngTemplateOutlet="templateRef; context: { $implicit: item, index: i }"></ng-container>
</div>

In the above code, we are using ng-template to define a template block that receives item and index as context variables. The let-item syntax assigns each item in the iteration to the item variable, and let-index="index" assigns the index to the index variable.

When using ngTemplateOutlet, we provide the context object to pass data into the template. The $implicit property inside the context object refers to the default context variable. In this case, item is assigned to $implicit, which means that within the template block, item can be accessed directly without using any additional template variable.

So, within the ng-template, the expression {{ $implicit }} is equivalent to {{ item }}, allowing you to access and display the current item value. You can also use index within the template as {{ index }}.

This usage of $implicit simplifies the template syntax when you have a single default variable inside the ng-template and makes the code more readable and concise.

ng-template and Template References

ng-template also allows us to access and use templates within our component logic using template references.

<ng-template #dynamicContent>
<p>{{ dynamicText }}</p>
</ng-template>

<button (click)="toggleContent()">Toggle Content</button>

<div *ngIf="showContent">
<ng-container *ngTemplateOutlet="dynamicContent"></ng-container>
</div>

In this example, we define an ng-template with the reference name #dynamicContent and use ngTemplateOutlet to render it inside a div when the showContent variable is true. We can manipulate the showContent variable in the component's logic to toggle the visibility of the dynamic content.

Advanced ng-template Techniques

ng-template provides advanced techniques for more complex scenarios. For instance, we can use ViewChild or ContentChild to manipulate templates programmatically.

<ng-template #tabContentTemplate>
<div>This is the content of a tab.</div>
</ng-template>

<div *ngFor="let tab of tabs">
<div class="tab-header" (click)="selectTab(tab)">{{ tab.title }}</div>
<div *ngIf="selectedTab === tab">
<ng-container *ngTemplateOutlet="tabContentTemplate"></ng-container>
</div>
</div>

In this example, we define an ng-template with the reference name #tabContentTemplate to represent the content of a tab. We use ngFor to iterate over an array of tabs and ngTemplateOutlet to render the template for the selected tab.

Using ng-template Techniques in multiple components

Create the ng-template: Define the ng-template in a shared module or a component that will be accessible by other components. For example:

<!-- shared-template.component.html -->
<ng-template #templateRef>
<!-- Content or UI elements here -->
</ng-template>

Export the ng-template reference: In the component where the ng-template is defined, make sure to export the template reference using the ViewChild decorator. For example:

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

@Component({
selector: 'app-shared-template',
templateUrl: './shared-template.component.html',
})
export class SharedTemplateComponent {
@ViewChild('templateRef') templateRef: TemplateRef<any>;
}

Import the shared module or component: In the component(s) where you want to use the ng-template, import the shared module or component that contains the ng-template. Make sure to add the shared module or component to the imports array of the respective module. For example:

import { Component } from '@angular/core';
import { SharedTemplateComponent } from 'path/to/shared-template.component';

@Component({
selector: 'app-other-component',
templateUrl: './other-component.component.html',
})
export class OtherComponent {
constructor(private sharedTemplateComponent: SharedTemplateComponent) {}
}

Use ng-template in the component: In the template of the component where you want to use the ng-template, you can use the ngTemplateOutlet directive to render the template. For example:

<!-- other-component.component.html -->
<div>
<ng-container *ngTemplateOutlet="sharedTemplateComponent.templateRef"></ng-container>
</div>

In the above example, we access the exported templateRef from the SharedTemplateComponent and use it within the ng-container using ngTemplateOutlet.

ng-template in Angular is a powerful directive that allows us to create reusable and dynamic templates. By leveraging ng-template, we can separate concerns, promote code reusability, and enhance the maintainability of our Angular applications. Whether it’s conditional rendering, dynamic lists, or sharing templates across multiple components, ng-template proves to be a valuable asset in your Angular toolkit. Embrace the power of ng-template to unlock a world of possibilities for building rich and interactive user interfaces in Angular applications.

--

--

Adebayo Oluwatobiloba
Adebayo Oluwatobiloba

Written by Adebayo Oluwatobiloba

As a senior frontend developer, I design and develop responsive web applications using Angular and React frameworks.

Responses (1)