Reputation: 1107
I'm doing content projection with @ContentChildren.
Now I have the need to put the components from the contentchildren query somewhere where I choose it to be. I also have to add an extra divider if not the last one in the array. So the reason is that based on a given list of components (content children) I need to create a new list with extra components in between...
How can this be done in Angular? I looked up for dynamic component injection but it's always starting from a component type being used to render a component. But in this case I already have the components in the ContentChildren query array...
Upvotes: 1
Views: 2712
Reputation: 8859
Here is working solution
To simulate what you want to implement, I've implemented two components, tabs
and tab
You can use these components as follows
<my-tabs>
<my-tab text="Tab 1"></my-tab>
<my-tab text="Tab 2"></my-tab>
<my-tab text="Tab 3"></my-tab>
</my-tabs>
<div>------------------</div>
<my-tab text="This is rendered itself" [single]="true"></my-tab>
Within TabComponent
, I've wrapped ng-content
with ng-template
so that I can inject it within component with @ViewChild(TemplateRef) content
.
@Component({
selector: 'my-tab',
template: `
<ng-template>
{{text}}
</ng-template>
<ng-container *ngIf="single">
<ng-container *ngTemplateOutlet="content"></ng-container>
</ng-container>
`
})
export class TabComponent {
@ViewChild(TemplateRef) content;
@Input() text;
@Input() single = false; // this will allow to use this component on its own
}
TabsComponent
@Component({
selector: 'my-tabs',
template: `
<div *ngFor="let tab of tabs; let isLast = last">
<ng-container *ngTemplateOutlet="tab.content"></ng-container>
<hr *ngIf="!isLast">
</div>
`,
})
export class TabsComponent {
@ContentChildren(TabComponent) tabs: QueryList<TabComponent>;
}
You can use tab.content
within *ngTemplateOutlet
directive.
<ng-container *ngTemplateOutlet="tab.content"></ng-container>
Upvotes: 3