I have 3 templates inside tempaltes.component
.
Inside item.component
I need to pick one of the templates conditionally, and pass it down to the header.component
to render, but somethingnot right with my code, please help.
Here is the complete code stackblitz
tempaltes.component.html
<ng-template #templateA let-item>
<p>{{ item.name }} Template A content here...</p>
</ng-template>
<ng-template #templateB let-item>
<p>{{ item.name }} Template B content here...</p>
</ng-template>
<ng-template #templateC let-item>
<p>{{ item.name }} Template C content here...</p>
</ng-template>
tempaltes.component.ts
@Component({
selector: 'app-templates',
templateUrl: './templates.component.html',
standalone: true,
imports: [],
})
export class TemplatesComponent {
@ViewChild('templateA') templateA!: TemplateRef<any>;
@ViewChild('templateB') templateB!: TemplateRef<any>;
@ViewChild('templateC') templateC!: TemplateRef<any>;
}
item.component.html
<app-header [headerTemplate]="selectedTemplate" [item]="item" />
item.component.ts
@Component({
selector: 'app-item',
templateUrl: './item.component.html',
standalone: true,
imports: [CommonModule, HeaderComponent],
providers: [TemplatesComponent],
})
export class ItemComponent {
templatesComponent = inject(TemplatesComponent);
@Input() item!: Item;
selectedTemplate: TemplateRef<any> | null = null;
ngOnInit() {
if (this.item.type) {
this.selectTemplate();
}
}
selectTemplate(): void {
if (this.item.type === 'type-a') {
this.selectedTemplate = this.templatesComponent.templateA;
} else if (this.item.type === 'type-b') {
this.selectedTemplate = this.templatesComponent.templateB;
} else if (this.item.type === 'type-c') {
this.selectedTemplate = this.templatesComponent.templateC;
}
}
}
header.component.html
<ng-container *ngTemplateOutlet="headerTemplate; context: { $implicit: item }"></ng-container>
header.component.ts
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
standalone: true,
imports: [CommonModule],
})
export class HeaderComponent {
@Input() headerTemplate: TemplateRef<any> | null = null;
@Input() item!: Item;
}
I believe the issue is within tempaltes.component.ts
and/or item.component.ts
.
You cant inject a component and access the view like that (in your code the template component is empty), you need to have it in the html of the component and access with view child, please find below a working example, I also changed to
ngAfterViewInit
since template will always be present, if you do inngOnInit
the view will be un-initialized and will give you null.html
ts
stackblitz