How do you hydrate a parent template with child data (Angular 11)

So I have two Angular Components, a parent & a child. I want to do the following:

  1. Define an ng-template in the parent component that references
    child functions/variables
  2. Pass that template as a parameter to the
    child component, and
  3. Have the child component display this
    template using its own instance data.

App.Component (Parent)

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

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {}
<reusable-component [customTemplate]="parentTemplate"></reusable-component>

<ng-template #parentTemplate>
  <p>Current color is {{currentColor}}</p>

  <button (click)="changeColorToRed()">
    CHANGE BACKGROUND COLOR TO RED
  </button>

  <button (click)="changeColorToGreen()">
    CHANGE BACKGROUND COLOR TO GREEN
  </button>
</ng-template>

Child Component (reusable-component)

import { Component, Input, OnInit, TemplateRef } from "@angular/core";

@Component({
  selector: "reusable-component",
  templateUrl: "./reusable-component.component.html",
  styleUrls: ["./reusable-component.component.css"]
})
export class ReusableComponentComponent implements OnInit {
  @Input() public customTemplate!: TemplateRef<HTMLElement>;
  currentColor = "white";

  constructor() {}

  ngOnInit() {}

  changeColorToRed() {
    const red = "#FF0000";
    document.body.style.background = red;
    this.currentColor = "red";
  }
  changeColorToGreen() {
    const green = "#00FF00";
    document.body.style.background = green;
    this.currentColor = "green";
  }
}
<ng-container [ngTemplateOutlet]="customTemplate || defaultTemplate">
</ng-container>

<ng-template #defaultTemplate>
  Hello, zuko here!
</ng-template>

How do I provide my parent template with the functions/instance variables from that child Component?

Here’s a Stackblitz with the whole project

1 thought on “How do you hydrate a parent template with child data (Angular 11)”

  1. Most of the things are fine. For passing data…

    Let us first start defining the data to be passed in the Child Component

    Child component TS

    currentColor = "white";
    constructor() {}
    
    ngOnInit() {}
    
    changeColorToRed() {
      const red = "#FF0000";
      document.body.style.background = red;
      this.currentColor = "red";
    }
    changeColorToGreen() {
      const green = "#00FF00";
      document.body.style.background = green;
      this.currentColor = "green";
    }
    
    data = { currentColor: this.currentColor, changeColorToRed: this.changeColorToRed, changeColorToGreen: this.changeColorToGreen };
    

    Now, we pass the context containing the data to the template. Use *ngTemplateOutlet instead of [ngTemplateOutlet] to support chaining

    Child component html

    <ng-container *ngTemplateOutlet="customTemplate || defaultTemplate; context: data">
    </ng-container>
    

    Now, we use the let- attribute to receive the parameters in the parent

    Parent component html

    <reusable-component [customTemplate]="parentTemplate"></reusable-component>
    
    <ng-template #parentTemplate let-currentColor="currentColor" let-changeColorToRed="changeColorToRed" let-changeColorToGreen="changeColorToGreen">
      <p>Current color is {{currentColor}}</p>
    
      <button (click)="changeColorToRed()">
        CHANGE BACKGROUND COLOR TO RED
      </button>
    
      <button (click)="changeColorToGreen()">
        CHANGE BACKGROUND COLOR TO GREEN
      </button>
    </ng-template>
    

    Stackblitz

    Reply

Leave a Comment