Show ng-content twice in Angular 10

Viewed 684

i'm working in a custom angular component where i need to show the projected content twice.

Let's say i have this html:

<app-awesome>
    <app-awesome-card *ngFor="let card of cards">
        <h1>{{card.title}}</h1>
        <img [src]="card.thumbnail">
    </app-awesome-card>
</app-awesome>

So, in awesome-card.component.html the projected content will be a few cards components that i want to project twice.

Could be this:

<div class="awesome-class">
    <ng-content select="app-awesome-card"></ng-content>
</div>
<div class="more-awesome-class">
    <ng-content select="app-awesome-card"></ng-content>
</div>

But this doesn't work because ng-content just "paste" the template, can't be duplicated. Even if i use ng-template like this:

<div class="awesome-class">
    <ng-container *ngTemplateOutlet="content"></ng-container>
</div>
<div class="more-awesome-class">
    <ng-container *ngTemplateOutlet="content"></ng-container>
</div>

<ng-template #content>
    <ng-content select="app-awesome-card"></ng-content>
</ng-template>

This will not work neither.

I been trying for a week to find an elegant solution but i couldn't. Only modifying the DOM directly but that's a bad practice. I've seen a few similar old questions and even a Github requests for this but seems that nobody at that time knew the answer.

PD: ContentChild will not work neither because it can't see through projected content (or something i believe)

EDIT If i could access the projected content info, i could manually render the content, but everything i tried fail

2 Answers

what I can offer is passing a template instead of passing a piece of html

<app-awesome>
    <ng-template> // or your own helper structural directive can be used.
    <app-awesome-card *ngFor="let card of cards">
        <h1>{{card.title}}</h1>
        <img [src]="card.thumbnail">
    </app-awesome-card>
    </ng-template>
</app-awesome>
@ContentChild(TemplateRef) contentTpl;
...
 
<div class="awesome-class">
    <ng-container *ngTemplateOutlet="contentTpl"></ng-container>
</div>
<div class="more-awesome-class">
    <ng-container *ngTemplateOutlet="contentTpl"></ng-container>
</div>

You need a . dot before the class

<ng-template #content>
    <ng-content select=".app-awesome-card"></ng-content>
</ng-template>
Related