How to use ng-template & TemplateRef in Angular

In this guide, we will learn what is ng-template and TemplateRef. We also learn how it works and how Angular makes use of them in various directives like ngIf,ngFor & ngSwitch etc. We can use ng-template with ngTemplateOutlet to display the dynamic templates, which is a separate tutorial.

What is ng-Template?

The <ng-template> is an Angular element, which contains the template. A template is an HTML snippet. The template does not render itself on DOM.

To understand let us create a new Angular Application and copy the following code to app.component.html

The above code generates the following output. The Angular does not render Say Hello. You won’t even find it as a hidden element in the DOM.

i.e because ng-template only defines a template. It is our job to tell angular where & when to display it.

There are few ways you can display the template.

  1. Using the ngTemplateOutlet directive.
  2. Using the TemplateRef & ViewContainerRef

Displaying the Template

ngTemplateOutlet

The ngTemplateOutlet, is a structural directive, which renders the template.

To use this directive, first, we need to create the template and assign it to a template reference variable (sayHelloTemplate in the following template).

We use the ngTemplateOutlet in the DOM, where we want to render the template.

The following code assigns the Template variable sayHelloTemplate to the ngTemplateOutlet directive using the Property Binding.

The content inside the ngTemplateOutlet directive is not displayed. It replaces it with content it gets from the sayHelloTemplate.

The ngTemplateOutlet is a very powerful directive. You can use it render templates, pass data to the template, pass the template to child components, etc. You can learn all these from our ngTemplateOutlet tutorial

TemplateRef & ViewContainerRef

What is TemplateRef?

TemplateRef is a class and the way to reference the ng-template in the component or directive class. Using the TemplateRef we can manipulate the template from component code.

Remember ng-template is a bunch of HTML tags enclosed in a HTML element <ng-template>

To access the above ng-template in the component or directive, first, we need to assign a template reference variable. #sayHelloTemplate is that variable in the code below.

Now, we can use the ViewChild query to inject the sayHelloTemplate into our component as an instance of the class TemplateRef.

Now, we need to tell Angular where to render it. The way to do is to use the ViewContainerRef.

The ViewContainerRef is also similar to TemplateRef. Both hold the reference to part of the view.

  • The TemplateRef holds the reference template defined by ng-template.
  • ViewContainerRef, when injected to via DI holds the reference to the host element, that hosts the component (or directive).

Once, we have ViewContainerRef, we can use the createEmbeddedView method to add the template to the component.

The template is appended at the bottom.

Angular makes use of ngTemplate extensively in its structural directives. But it hides its complexities from us.

ng-template with ngIf

You might have used ngIf a lot of times. Here is how we use it. We use an * before ngIf

There is another way to write the above code. That is using the ng-template syntax. To do that follow these steps

  1. Create a new element ng-template and bind ngIf to it
  2. Use the property binding syntax [ngIf]="selected" instead of *ngIf="selected"
  3. Move the div element on which ngIf is attached inside the ng-templete

The code works just like a normal *ngIf would do.

Behind the scenes, Angular converts every *ngIf to ng-template Syntax. In fact, it does so every structural directive like ngFor, ngSwitch, ngTemplateOutlet, etc

How it works

To understand how structural directives using ng-template works let us look at ttIf directive which we built in the tutorial custom structural directive. The ttIf directive is a simplified clone of *ngIf.

Create tt-if.directive.ts and add the following code. Also, remember to declare the ttIfDirective in app.module.ts

Open the app.component.html. You can use both <div *ttIf="selected"> and<ng-template [ttIf]="selected"> syntax.

app.component.ts

Now let us look at the directive code. We are injecting ViewContainerRef and TemplateRef instances in the constructor

We looked at ViewContainerRef in the previous section. It contains the reference to the host element that hosts our directive.

In the previous example, we used the ViewChild to get the reference to the template. But it is not possible here. Hence we use the Angular Dependency Injection to inject the template into our directive using the TemplateRef DI token.

We use the *notation to tell Angular that we have a structural directive and we will be manipulating the DOM. It basically tells angular to inject the TemplateRef. When we attach our directive to an ng-template, and ask for the TemplateRef in the constructor, the Angular injects the reference to the template enclosed by the ng-template.

The Template is inserted into the DOM when the condition is true. We do that using the createEmbeddedView method of the ViewContainerRef. The clear removes the template from the DOM

Multiple Structural Directives

You cannot assign multiple Structural Directives on a single ng-template.

For Example, the ngIf & ngFor on same div, will result in an an Template parse errors

You can use ng-container to move one directive to enclose the other as shown below.

ng-template with ngIf, then & else

The following code shows the ng-template using the ngIf, then & else example.

Here we use the ng-template specify the template for the then & else clause. We use the template reference variable to get the reference to those blocks.

In the *ngIf condition we specify the template to render by pointing to the template variable to the then & else condition.

The above ngif can be written using the ng-template syntax.

ng-template with ngFor

The following ngFor Directive.

Is written as follows using the ng-template syntax

ng-template with ngSwitch

The following is the example of ngSwitch.

The above example using the ng-template with ngSwitch. Note that ngSwitch is not a structural directive but ngSwitchCase & ngSwitchDefault are.

Reference

  1. NgTemplateOutlet
  2. Structural directives

Source Code

  1. ngtemplateoutlet
  2. ViewContainerRef
  3. ttIf Directive

4 thoughts on “How to use ng-template & TemplateRef in Angular”

  1. Type ‘HTMLTemplateElement’ is missing the following properties from type ‘TemplateRef’: elementRef, createEmbeddedView

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top