I had the same problem and I was searching for the same solution you're asking for, but I didn't found any.
I solved the problem with inheritance.
You have to create a component without any template which will be the parent class. This component will contain all the logic you need. I insert only an Input just to show how it works:
base.component.ts
@Component({
selector: 'base',
template: ''
})
export class BaseComponent{
@Input()
text: string;
}
Then you have to create different templates as different components which extends BaseComponent:
template1.component.ts
@Component({
selector: 'template1',
template: '<button>{{text}}</button>'
})
export class Template1Component extends BaseComponent{}
template2.component.ts
@Component({
selector: 'template2',
template: '<input [value]="text">'
})
export class Template2Component extends BaseComponent{}
And now you can simply use them like this:
app.component.html
<button (click)="template = (template == 1) ? 2 : 1">Change template</button>
<br><br>
<ng-container [ngSwitch]="template">
<template1 text="Template1 input text" *ngSwitchCase="1"></template1>
<template2 text="Template2" *ngSwitchCase="2"></template2>
</ng-container>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
template = 1;
}
Take a look to the working example here
Hope this could help.