How to Use ngTemplateOutlet in Angular

Dynamic Template Rendering in Angular

ngTemplateOutlet is a directive used to dynamically render content from a template. It allows you to reuse and inject templates at runtime, providing flexibility and component composition.

In Angular, you can leverage the power of ngTemplateOutlet and ngTemplateOutletContext directives to dynamically render templates based on certain conditions. In this blog post, we’ll explore how to create a customizable grid that renders different templates for each item based on a property value. Let’s get started!

Prerequisites

Make sure you have the latest version of Angular CLI installed on your machine.

Setting up the Project

  1. Create a new Angular project by running the following command in your terminal:
ng new dynamic-grid
  1. Navigate to the project directory:
cd dynamic-grid
  1. Open the project in your preferred code editor.

Creating the Grid Component

  1. Generate a new component named grid by running the following command:

    ng generate component grid
    
  2. Open the generated grid.component.ts file and replace the code with the following:

    import { Component, ViewChild, TemplateRef } from '@angular/core';
    
    @Component({
      selector: 'app-grid',
      templateUrl: './grid.component.html',
      styleUrls: ['./grid.component.css'],
    })
    export class GridComponent {
      @ViewChild('specialTemplate', { static: true })
      specialTemplate!: TemplateRef<any>;
      @ViewChild('defaultTemplate', { static: true })
      defaultTemplate!: TemplateRef<any>;
    
      items = [
        { name: 'Item 1', description: 'Description 1', special: false },
        { name: 'Item 2', description: 'Description 2', special: true },
        { name: 'Item 3', description: 'Description 3', special: false },
      ];
    
      getItemTemplate(item: any): any {
        return item.special ? this.specialTemplate : this.defaultTemplate;
      }
    }
    
  3. Next, open the grid.component.html file and replace the code with the following:

    <div class="grid-container">
      <div class="grid-item" *ngFor="let item of items">
        <ng-container
          [ngTemplateOutlet]="getItemTemplate(item)"
          [ngTemplateOutletContext]="{ $implicit: item }"
        ></ng-container>
      </div>
    </div>
    
    <ng-template #defaultTemplate let-item>
      <div class="default-template">
        <h4>{{ item.name }}</h4>
        <p>{{ item.description }}</p>
      </div>
    </ng-template>
    
    <ng-template #specialTemplate let-item>
      <div class="special-template">
        <h4>{{ item.name }}</h4>
        <p>{{ item.description }}</p>
        <p class="special-message">Special Item!</p>
      </div>
    </ng-template>
    
  4. Finally, add the necessary styles in the grid.component.css file:

    .grid-container {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      grid-gap: 20px;
    }
    
    .grid-item {
      border: 1px solid #ccc;
      padding: 20px;
    }
    
    .default-template {
      background-color: #f0f0f0;
    }
    
    .special-template {
      background-color: #ffcc99;
    }
    
    .special-message {
      font-weight: bold;
    }
    

Understanding let-item and $implicit

In the grid.component.html file, you’ll notice that we’re using the let-item syntax within the template definitions:

<ng-template #defaultTemplate let-item>
  <!-- Default template content -->
</ng-template>

<ng-template #specialTemplate let-item>
  <!-- Special template content -->
</ng-template>

The let-item syntax allows us to define a template input variable named item. This variable represents the current item being iterated over in the ngFor loop. We can then access the properties of the item object within the template.

The $implicit property within the ngTemplateOutletContext defines the default context for the template. By setting it to item, we make the item object available within the template as the default context. This allows us to directly access the item properties without explicitly referencing item.

Understanding @ViewChild and Static

In the component class (grid.component.ts), we define two @ViewChild properties to access the template references:

@ViewChild('specialTemplate', { static: true })
specialTemplate!: TemplateRef<any>;

@ViewChild('defaultTemplate', { static: true })
defaultTemplate!: TemplateRef<any>;

Here, @ViewChild decorator allows us to query and access the template references named 'specialTemplate' and 'defaultTemplate'. The { static: true } configuration option specifies that these references should be resolved at compile-time rather than at runtime.

The specialTemplate and defaultTemplate properties are declared with the ! operator. In TypeScript, the ! operator is the non-null assertion operator. It tells the compiler that the properties will be assigned a value at runtime and should not be considered potentially undefined or null. Since we are using @ViewChild with static: true, we can guarantee that the template references will be available at runtime.

The getItemTemplate method in the component class determines which template to use based on the item.special condition:

getItemTemplate(item: any): any {
  return item.special ? this.specialTemplate : this.defaultTemplate;
}

Here, this.specialTemplate and this.defaultTemplate refer to the template references obtained through @ViewChild. The $implicit property in the ngTemplateOutletContext provides the current item as the implicit value within the template.

By using this approach, we can dynamically switch between different templates based on the item.special property. This allows us to customize the rendering of each item in the grid dynamically.

Running the Application

  1. Save all the changes and start the Angular development server by running the command:

    ng serve
    
  2. Open your browser and navigate to http://localhost:4200 to see the dynamic grid in action.

The grid will render a list of items, and each item will be displayed using a different template based on the special property. If the special property is true, the item will be displayed with a special template that includes an additional message. Otherwise, it will use the default template.

I hope this blog post helps you understand the concept of dynamic template rendering and how it can be applied in your Angular projects. Feel free to explore further and customize the templates and styles as per your requirements.

Happy coding!

Next Post Previous Post
No Comment
Add Comment
comment url