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?
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() .
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.
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.
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.
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>
<div class="box">
<ng-container [ngTemplateOutlet]="template" [ngTemplateOutletContext]="context"></ng-container>
</div>
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;
}
}
<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>
Working demo is here https://stackblitz.com/edit/angular-yzkwrq
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With