Angular ng-template and ng-container

Introduction 

This post will describe the advanced features of Angular. The ng-template and related ng-container directive are powerful features for some use-cases in our Angular project.  We will study each of these directives in detail. They are designed to be used together. 

Description: ng-template

ng-template directive represents an Angular template. The content of this tag will be HTML content. But this directive elements will be rendered only if it is used with structural directives.
  • The content of this directive will not be displayed directly.
  •  elements will be rendered only if it is used with structural directives like ngIf, ngFor, ngSwitch.
  • Before rendering the view, the ng-template and its content are replaced by a comment by Angular. comment. 
  • In the ng-template directive, we will only specify the template. Usage with any structural directive will able to render something on the screen.
  • We need to add some structural directive to tell ng-template what to do with the specified template.
  • All structural directives are using ng-template under the hood.
    <div *ngIf="condition">Template will render if the condition is true.</div> 
    The above statement works as below under the hood:
    <ng-template [ngIf]="condition">
    <div>Template will render if the condition is true.</div>
    </ng-template>
  • The ng-template will not be seen in the DOM. It will be replaced by comment. That's why ng-template is not a true wen element.
  • The asterisk is used with structural directives. All the structural directives evaluate to ng-template under the hood. So Asterisk(*) is the notation for ng-template.
  • Example of ng-template
  • <p>Hello!</p>
       <ng-template>
          <p>Angular</p>
       </ng-template>
    <p>World</p>
    The above code will be shown as below:

Description: ng-container

ng-container is a grouping element that doesn't interfere with HTML and CSS as Angular doesn't add it in the DOM. We will see the following scenarios for the usage of ng-container.

Scenario 1: Multiple Structural Directive on a single element
If we try to apply two structural directives on the same element then what will happen?
<div *ngIf="condition" *ngFor="let e of elements;">...</div>
The above statement will throw an error as mentioned below:
Uncaught Error: Template parse errors:
Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with *

To make things work we need to do something like this:
<div *ngIf="condition">
   <div *ngFor="let e of elements;">
      <p>HTML CONTENT</p>
   </div>
</div>

We need to add an extra <div> tag to avoid the error. The creation of an extra div element in the DOM is non-desirable. Using ng-container we can avoid this error without adding an extra element.
<ng-contanier *ngIf="condition">
   <div *ngFor="let e of elements;">
      <p>HTML CONTENT</p>
   </div>
</ng-container>
Scenario 2: Template UI getting a break because of grouping elements with extra <div> or <span>

We need to group native HTML elements to apply some condition to elements. This sometimes breaks our UI appearance as CSS will never expect these things. 

Suppose we have a <div> tag inside a <p> tag to apply some condition using ngIf directive. Example:
<p>I turned on my laptop
  <div *ngIf="condition">
    asked by {{employee.name}}
  </div>
  and continued with my work.
</p>
Suppose if we have a CSS style for something like
p div{
   color:red;
}
Then this style will get applied to this statement as well. But it was not intended to be applied here. So it's better to use <ng-container> as it will not interfere with CSS as well.
<p>I turned on my laptop
  <ng-container *ngIf="condition">
    asked by {{employee.name}}
  </ng-container>
  and continued with my work.
</p>
Scenario 3: When in HTML some elements require all immediate children of a specific type.
In HTML some elements can only be rendered if they are used with the specific parent element or some elements require all immediate descendants of a particular type. For example, the select element requires immediate option element. You can't wrap option in any native HTML element like <div> or <span> for conditions. So we can use <ng-container> to wrap <option> element with conditions.
Example:
<select>
  <ng-container *ngFor="let e of elements">// ng-container used for applying condition
    <ng-container *ngIf="condition'"> 
      <option>......</option>
    </ng-container>
  </ng-container>

</select>

The <ng-container> is a syntax element identified by the Angular parser. It's not a directive, component, class, or interface.

Comments

Post a Comment