treycrossley
treycrossley

Reputation: 143

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

Upvotes: 0

Views: 261

Answers (1)

T. Sunil Rao
T. Sunil Rao

Reputation: 1247

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

Upvotes: 1

Related Questions