Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Content Projection with iteration

myComponent.html - <my-component>

<ng-container *ngFor="let item of dataProvider">
    <ng-template *ngTemplateOutlet="tmpContent; context: {$implicit: item, item: item}">
    </ng-template>
</ng-container>

<ng-template #tmpContent let-item="item">
    <div>
        {{item.id}}
        <ng-content></ng-content>
    </div>
</ng-template>

And the usage:

 <my-component dataProvider='source'>
    <ion-label> test </ion-label>
 </my-component>

It seems iterate the correct number of times, but displays the <ion-label>, which is content projected only once in the last iteration. So is it possible to content project this ion-label every time. I need to be implemented with content projection as instead of ion-label could be anything, so will be passed in declarative way.

like image 978
Dimitar Marinov Avatar asked Dec 21 '25 06:12

Dimitar Marinov


1 Answers

You can pass a the label as a template and then reuse the template inside your component. In the component add a new input called labelTemplate that is passed a TemplateRef. Then in the view, you can reference it like any template - I assumed you wanted it nested in the template you provided in your example, but there is no reason it couldn't be in the main for loop block.

export class MyComponentComponent {
  /** The template used to display the label */
  @Input() labelTemplate?: TemplateRef<{ $implicit: unknown }>;
}
<ng-template #tmpContent let-item="item">
  <div>
    {{item.id}}
    <ng-template *ngTemplateOutlet="labelTemplate; context: {$implicit: item.name }" />
  </div>
</ng-template>

In the consuming component's html template, add a label template anywhere within the markup - it doesn't have to be projected. The reference to the template is passed to the labelTemplate property attribute on the my-component element.

<my-component dataProvider='source' [labelTemplate]="label">
  <ng-template #label let-content>
    <ion-label> test </ion-label>
  </ng-template>
</my-component>
like image 85
Daniel Gimenez Avatar answered Dec 23 '25 23:12

Daniel Gimenez