I know this question is old, but hopefully this helps people who are attempting similar things.
The unfortunate thing about what you want is that the easiest way to do it is to simply make each template its own component. Otherwise, you have to inject and sanitize HTML. They removed ng-include and similar capabilities because of security risks of injecting un-sanitized HTML. Its wouldn't be that much of a P.I.T.A if you didn't have to specifically import and declare all those additional components in your module, but alas...
You can create a simple directive that will get templateRefs, and then query elements on your page that have those directives, get the template ref from it, and insert them elsewhere. This would at least let you keep all the templates in a separate file. I usually put 3 or 4 templates in a separate component and include them in the component that wants to render them with . I'll describe how to do that.
Directive to get template refs
import { Directive, TemplateRef, Input } from '@angular/core';
@Directive({
selector: 'get-template',
})
export class GetTemplateDirective {
@Input() name: string;
constructor(public template: TemplateRef<any>) { }
}
Then for the templates, create a super simple component that has them all
@Component({
selector: 'sub-component-templates',
template: `
<ng-template get-template [name]="tpl1">
Put Whatever here, including other components if you please
</ng-template>
<ng-template get-template [name]="tpl2">
Different template here
</ng-template>
... and so on and so on...
`
})
export class Templates { }
Import all the relevant new components into your module, then include them inside your main component that will render the templates
I usually do it with ng-content so its clear in the parent component that this component is referencing another one for its templates.
For example, in the parent..
<sub-component>
<sub-component-templates></sub-component-templates>
</sub-component>
Then in the sub component
import { Component, ViewChild, ContentChildren, QueryList } from '@angular/core';
import { GetTemplateDirective } from 'wherever';
@Component({
selector: 'sub-component',
template: `
<ng-content></ng-content>
<div #templateRenderer></div>
`
})
export class SubComponent {
@ViewChild('templateRenderer',{read:ViewContainerRef}) anchor: ViewContainerRef;
@ContentChildren(GetTemplateDirective) templates: QueryList<GetTemplateDirective>;
ngAfterContentInit() {
... at this stage, you will have access to all the included templates with that directive on them. You can perform your logic to choose which one you want. Once you have selected the proper one, you can embed it like so ...
let desiredTemplateName = 'whatever';
for (let t of this.templates.toArray()) {
if(t.name === desiredTemplateName) {
this.anchor.createEmbeddedView(t.template);
break;
}
}
}
}
You can see that this is ridiculously complicated for what you are trying to do. It would be easier to just create them as separate components, and use the ngSwitchCase to choose the proper one. The advantage to the method I've described above is that it lets you keep your templates wherever you want really, and you could include 100 in the same external component (which is really no more than the bare minimum decorated component with a template) if you wanted, or move them around with a service, or whatever.
See here for a working example of how to use the compiler - https://plnkr.co/edit/fdP9Oc?p=info
Still quite complicated...
If you store the template as a property of the class, you could change it later as needed. Just add a template ref import...
import { Component, ViewChild, ContentChildren, QueryList, TemplateRef } from '@angular/core';
and then create a property
template: TemplateRef<any>;
Then later you could switch it out with one from your querylist and create the embeddedview again using the view container's methods.
Angular 2 / 4 made certain things easier... and made certain things waaaaaay more difficult. But I guess in this case, its in the name of security.