We have built a generic master-detail component that will render a specific detail component based on a @Input EntityType property that it gets provided with. In the master detail component template, we call a wrapper/factory component that will render the appropriate detail component based on entityType:
@Component({
selector: 'master-detail',
template: `
<div>
<grid></grid>
<detail-wrapper> [entityType]=entityType></detail-wrapper>
</div>
`,
})
export class MasterDetailComponent {
@Input() entityType: string ;
...
}
@Component({
selector: 'detail-wrapper',
template: `
<ng-container [ngSwitch]="entityType">
<comp-a *ngSwitchCase="'A'"></comp-a>
<comp-b *ngSwitchCase="'B'""></comp-b>
<comp-default *ngSwitchDefault></comp-default>
</ng-container>
`,
})
export class DetailWrapperComponent {
@Input() entityType: string ;
...
}
The detail component can itself contain another master-detail component (like russian dolls). However when this happens, my code won't run because of circular dependency:
master-detail -> detail-wrapper -> compA -> master-detail
I know I could break the circular dependency this by creating duplicates for each level using inheritance :
export class MasterDetailLevel2Component extends MasterDetailComponent {...}
export class CompALevel2Component extends CompAComponent {...}
But that really doesn't look like a proper solution and involves creating classes for each recursion level.
Another possibility I see would be to use ComponentFactoryResolver instead of DetailWrapperComponent. The MasterDetailComponent would then be provided with a component factory interface (therefore removing the linking between the concrete implementation). But with this solution, I'm loosing template bindings.
Is there a better way to get out of this ?