40

I'm looking for solution to pass current component scope data into ng-content directive.

I've app-table component template with data I want to pass into child content, using some solution like this:

<!-- some html before -->
<table>
    <!-- complex header markup with sorting/filtering support -->

    <tr *ngFor="let item of data">
         <ng-content [value]="item"></ng-content> //how to pass data?
    </tr>
</table>
//some html after

And page template where I want to use this data:

<app-table>
     <td>{{value.Name}}</td>
     ...
</app-table>

Is this possible?

VadimB
  • 5,533
  • 2
  • 34
  • 48
  • what about @Input? – toskv Jan 06 '17 at 17:04
  • I need `ng-content` as I have many other templates inside `app-table`, like empty table, etc – VadimB Jan 06 '17 at 17:07
  • 3
    I guess you're looking for `ngForTemplate` or `NgTemplateOutlet` http://stackoverflow.com/questions/39974126/how-to-pass-an-expression-to-a-component-as-an-input-in-angular2/39977298#39977298 – yurzui Jan 06 '17 at 17:08
  • @VadimB have you found a solution to this? I am facing exactly same problem here – eddyP23 May 15 '17 at 08:52
  • @yurzui, unfortunately no :( I had no time to dive deeper inspecting this problem. Also do not found any useful information regarding this feature on official documentation. – VadimB May 15 '17 at 09:03

3 Answers3

22

I faced the same issue, for more clarification, I added your example working.

<!-- some html before -->
<table>
    <!-- complex header markup with sorting/filtering support -->

    <tr *ngFor="let item of data">
      <ng-template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{$implicit: item}"></ng-template>
    </tr>
</table>
//some html after

In the Component, you need to declare templateRef like this.

export class AppTableComponent {
  ...
  @ContentChild(TemplateRef) templateRef: TemplateRef<any>;

  ...
}

Then use your component like this.

<app-table>
 <ng-template let-item>
     <td>{{item.Name}}</td>
     ...
 </ng-template>
</app-table>
emanuel
  • 339
  • 3
  • 7
  • 5
    `ng-template` is one of the most confusing parts of Angular, IMO. Thanks for sharing this. It makes a great reference every time I have to look it up. – WebWanderer Jul 05 '21 at 05:44
14

I think you could find your answer here: Angular 2 passing html to ng-content with bindings.

The ng-content component is badly documented, unfortunately. It will be soon, according to the Angular GitHub issue (https://github.com/angular/angular.io/issues/3099).

DotBert
  • 1,262
  • 2
  • 16
  • 29
5

for advance:

  1. set name for template for use more than one template
  2. pass more than one parameter

use this code:

<table>
  <tr *ngFor="let item of data">
    <ng-container *ngTemplateOutlet="tmplRef;
            context: {$implicit: item, item2: item2}">
    </ng-container>
    <ng-container *ngTemplateOutlet="tmplRef2;
            context: {$implicit: item, item2: item2}">
    </ng-container>
  </tr>
</table>

export class AppTableComponent {
  ...
  @ContentChild('tmpl') tmplRef: TemplateRef<any>;
  @ContentChild('tmpl2') tmplRef2: TemplateRef<any>;
  ...
}

<app-table>
  <ng-template #tmpl let-item let-item2="item2">
    <td>{{item.Name}}</td><td>{{item2.Name}}</td>
  </ng-template>
  <ng-template #tmpl2 let-item let-item2="item2">
    <td>{{item.Name}}</td><td>{{item2.Name}}</td>
  </ng-template>
</app-table>
Hamid Taebi
  • 357
  • 2
  • 12