Reputation: 747
Let me start by saying that I did look at several other questions regarding ngTemplateOutlet (like: Angular 2 dynamically change the template in the ngTemplateOutlet or ngTemplateOutlet with dynamic value), but they didn't really cover what I'm trying to do, or maybe I can't see how the logic can be applied to what I'm trying to achieve.
My goal:
I have a page, where I want to be able to change the order of my templates being displayed.
I have 2 simple templates, "colors" and "fonts":
<ng-template #colors>
Red: #FF0000
Green: #00FF00
Blue: #0000FF
</ng-template>
<ng-template #fonts>
Helvetica
Verdana
Times New Roman
</ng-template>
I have no problem showing these in a predefined order:
<div>
<ng-container *ngTemplateOutlet="colors"></ng-container>
</div>
<div>
<ng-container *ngTemplateOutlet="fonts"></ng-container>
</div>
My problem is, I don't know how to display these templates based on a variable on my component. My component holds an array variable, which contains the order and names of the templates I want to display:
public order: ['fonts', 'colors'];
Notice here, that the order of the templates are switched, so "fonts" should be shown first, then "colors".
My idea was to assign the *ngTemplateOutlet value based on the order variable like this:
<ng-container [ngTemplateOutlet]="order[0]"></ng-container>
<ng-container [ngTemplateOutlet]="order[1]"></ng-container>
But when I do so, I get the following console error:
TypeError: templateRef.createEmbeddedView is not a function
I'm not exactly sure where I'm going wrong with this, or how I can get the *ngTemplateOutlet to take it's template name from an array variable on my component.
I created this stackblitz for it: https://stackblitz.com/edit/angular-q7uqbx
Any help would be much appreciated!
Kind regards,
Jesper
Upvotes: 1
Views: 4167
Reputation: 1827
You need to use ViewChild to get reference to the templates and store templates in the array.
Component:
import { Component, ViewChild, TemplateRef } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
@ViewChild('colors') colors: TemplateRef<any>;
@ViewChild('fonts') fonts: TemplateRef<any>;
public order = [];
ngAfterViewInit(): void {
this.order = [this.fonts, this.colors];
}
}
Template:
<ng-template #colors>
Red: #FF0000
Green: #00FF00
Blue: #0000FF
</ng-template>
<ng-template #fonts>
Helvetica
Verdana
Times New Roman
</ng-template>
<ng-container [ngTemplateOutlet]="order[0]"></ng-container>
<ng-container [ngTemplateOutlet]="order[1]"></ng-container>
Upvotes: 5