Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create TemplateRef and insert it in component's template

Tags:

angular

Angular 5.0.2 Based on the example provided on NgTemplateOutlet https://angular.io/api/common/NgTemplateOutlet

I want to know if there's a way to dynamically create a TemplateRef and then inject it into component's template.

For example let's say a component has the following template

<ng-container *ngTemplateOutlet="eng; context: myContext"></ng-container>
<ng-template #eng let-name><span>Hello {{name}}!</span></ng-template>

component code

class NgTemplateOutletExample {
  myContext = {$implicit: 'World'};
}

What I want is to transform this into a component with the following template

<ng-container *ngTemplateOutlet="eng; context: myContext"></ng-container>

and component code like this

class NgTemplateOutletExample {
  eng:TemplateRef = this.createTemplateRef('<ng-template #eng let-name><span>Hello {{name}}!</span></ng-template>');
  myContext = {$implicit: 'World'};
}

Is it possible to create TemplateRef from a string?

like image 554
Doua Beri Avatar asked Nov 18 '17 23:11

Doua Beri


People also ask

What is a TemplateRef?

TemplateReflink Represents an embedded template that can be used to instantiate embedded views. To instantiate embedded views based on a template, use the ViewContainerRef method createEmbeddedView() .

Can we use ng-template inside ng-template?

ng-template is an Angular element that is used for rendering HTML in a template. However, it is not rendered directly on DOM. If you include an ng-template tag to a template, the tag and the content inside it will be replaced by comment upon render.

How do I pass a ng-template?

In order to have a template rendered in that container, we use the *ngTemplateOutlet to pass a reference to an existing template, such as the one we created earlier. We use @Input to pass a TemplateRef to our component.

What is TemplateRef and ViewContainerRef?

TemplateRef is an embedded template which you can use in ViewContainerRef. createEmbeddedView to create Embedded View. *ngFor is doing the same, it reads the element as a TemplateRef and injects mutiple times to create view with data. TemplateRef cannot be used as an element for css decorations in .ts.


1 Answers

What you want is to have dynamic templates. So that you can put the template later without changing the same component.

Now how can you achieve this ?

Create the main component renders the template. <main-component>

main.component.html

<div class="box">
  <ng-container [ngTemplateOutlet]="template" [ngTemplateOutletContext]="context"></ng-container>
</div>

main.component.ts

import { Component, OnInit, TemplateRef, ContentChild } from '@angular/core';

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit {

  constructor() { }

  @ContentChild("template")
  template :TemplateRef<any>;

  ngOnInit() {

  }

  get context(){
    return this;
  }

}
  • Now you can the same component with different templates*

app.component.html

<app-main>
  <ng-template #template>Content From First Template</ng-template>
</app-main>
<br>
<app-main>
  <ng-template #template>Content From Second Template</ng-template>
</app-main>

Output

enter image description here

Working demo is here https://stackblitz.com/edit/angular-yzkwrq

like image 111
Sunil Singh Avatar answered Sep 18 '22 15:09

Sunil Singh