Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render multiple ng-content inside an ngFor loop using Angular 4?

Tags:

angular

I'm trying to display two differents ng-content inside two ngFor loops. But as described in this answer, Angular can't project ng-content multiple times.

I tried this solution, but this does not allow me to project multiple times my content, only to display it at different places depending on an ngIf condition.

Here's my actual code :

An example parent component (any component using app-table). That's what I want to do.

<app-table [data]="myData">
  <div lineHeader let-line>
    {{line.name}}
  </div>
  <div lineContent let-element>
    {{element.name}}
  </div>
</app-table>

The child component (app-table). Here I can do everything while the parent component keeps working the same way.

<div *ngFor="let line of data">
  <ng-content select="[lineHeader]"></ng-content>
  <div *ngFor="let element of line">
    <ng-content select="[lineContent]"></ng-content>
  </div>
</div>
like image 567
Arthur Chaloin Avatar asked Oct 27 '17 13:10

Arthur Chaloin


1 Answers

The best option in your case would be trancluding ng-template by using ngTemplateOutlet like:

<app-table [data]="myData">
  <ng-template #lineHeader let-line>
    <div>
     {{line.name}}
    </div>
  </ng-template>
   <ng-template #lineContent let-element>
    <div>
      {{element.name}}
    </div>
   </ng-template>
</app-table>

app-table.component.ts

@Component({
  selector: 'app-table',
  template: `
    <div *ngFor="let line of data">
      <ng-container *ngTemplateOutlet="lineHeaderTmpl, 
                     context: { $implicit: line }"></ng-container>
      <div *ngFor="let element of line.values">
        <ng-container *ngTemplateOutlet="lineContentTmpl, 
                       context: { $implicit: element }"></ng-container>
      </div>
    </div>
  `
})
export class AppTableComponent  {
  @Input() data: any;

  @ContentChild('lineHeader') lineHeaderTmpl: TemplateRef<any>; 
  @ContentChild('lineContent') lineContentTmpl: TemplateRef<any>; 
}

Stackblitz Example

like image 80
yurzui Avatar answered Oct 14 '22 03:10

yurzui