Stefano Tucci
Stefano Tucci

Reputation: 13

Component with ngFor that accept template and pass it to the children, how to do it?

i'm developing an Angular 6 app. I have a component BelloComponent that render a list passed on @Input items.

@Component({
  selector: 'bello',
  template: `
    <ul *ngIf="items?.length">
      <li *ngFor="let item of items">
        ???
      </li>
    </ul>
`
})
export class BelloComponent {
  @Input() items: Array<Object>;
}

And the consumer, AppComponent uses BelloComponent. How to render the list pasisng it from AppComponent a template inside the BelloComponent tag?

@Component({
  selector: 'my-app',
  template: `
<bello [items]="cacche_list">
  <b>{{ name }}, puzza value: {{ puzza }}</b>
</bello>`
})
export class AppComponent  {

  cacche_list = [
    { name: 'cacca 1', puzza: 3 },
    { name: 'cacca 2', puzza: 5 },
    { name: 'cacca 3', puzza: 66 },
    { name: 'cacca 4', puzza: 5 },
    { name: 'cacca 5', puzza: 2 },
    { name: 'cacca 6', puzza: 12 },
  ];
}

The stackblitz is this: https://stackblitz.com/edit/angular-exbhsv?file=src%2Fapp%2Fapp.component.ts

I think i'm missing something, how to tell to BelloComponent how to render the element in the ngFor? How to have access to the single item rendered from AppComponent?

Upvotes: 1

Views: 550

Answers (3)

spielbug
spielbug

Reputation: 1371

Using transclusion you can deal with it this way

@Component({
 selector: 'bello',
 template: `
    <ul *ngIf="items?.length">
     <li *ngFor="let item of items">
       <ng-container *ngTemplateOutlet="liTemplate; context: { $implicit: item}"></ng-container>
     </li>
   </ul>
 `
})
export class BelloComponent {
  @ContentChild(TemplateRef) liTemplate: TemplateRef<any>;
  @Input() items: Array<Object>;
}

and in your container component

@Component({
  selector: 'my-app',
  template: `
<bello [items]="cacche_list">
  <ng-template let-item>
     <b>{{ item.name }}, puzza value: {{ item.puzza }}</b>
  </ng-template>
</bello>`
})
export class AppComponent  {

  cacche_list = [
    { name: 'cacca 1', puzza: 3 },
    { name: 'cacca 2', puzza: 5 },
    { name: 'cacca 3', puzza: 66 },
    { name: 'cacca 4', puzza: 5 },
    { name: 'cacca 5', puzza: 2 },
    { name: 'cacca 6', puzza: 12 },
  ];
}

For further informations see this blog https://www.kaels-kabbage.com/post/angular-transclusion-with-parameters/

Upvotes: 1

Aviso
Aviso

Reputation: 695

You can simply use <ng-content></ng-content> in bello component



@Component({
  selector: "bello",
  template: `
    <ul *ngIf="items?.length">
      <li *ngFor="let item of items">
        <ng-content></ng-content>
      </li>
    </ul>
  `
})
export class BelloComponent {
  @Input() items: Array<Object>;
}

Upvotes: 0

Sachila Ranawaka
Sachila Ranawaka

Reputation: 41445

only thing that missing is the {{item.name}} in your ngFor

<ul *ngIf="items?.length">
  <li *ngFor="let item of items">
    {{item.name}}
  </li>
</ul>

Demo

Upvotes: 0

Related Questions