4

I have a list component which shows only names. list component should be able to take custom template which will be given by user.

List Component

import {Component } from 'angular2/core';

@Component({
  selector: 'my-list',
  template: `<p>This is List</p>
     <ul>
       <li *ngFor="#i of data"><div class='listItem'>{{i.name}}</div></li>
    </ul>`
})
export class MyList implements OnInit{ 
    data: Array<any> = [{name: 'John', age: 26},{name: 'Kevin', age: 26},  {name:'Simmons', age:26}];
}

My Requirement

<my-list>
   <div>{{i.name}}-{{i.age}}</div> //user should be able to provide custom template like this
</my-list>

I tried this with ng-content but it throws error. In angular 1 same thing used to work with transcluded content. do we have any alternative of manual transclusion in angular 2 and if not then how could we implement this feature in angular2.

Here is Plunker

flob
  • 3,760
  • 2
  • 34
  • 57
Akhlesh
  • 2,389
  • 1
  • 16
  • 23

3 Answers3

12

You need to use ngForTemplate, I've created PrimeNG DataList and many other DataComponents using this technique and it works great. Demo;

http://www.primefaces.org/primeng/#/datalist

Code;

https://github.com/primefaces/primeng/blob/master/src/app/components/datalist/datalist.ts

In your component, define a templateRef with contentchild;

@ContentChild(TemplateRef) itemTemplate: TemplateRef;

Your template becomes;

template: `<p>This is List</p>
     <ul>
       <template ngFor [ngForOf]="data" [ngForTemplate]="itemTemplate"></template>
    </ul>`

So that your users can define content like;

<my-list>
   <template #anything>
        <div>{{anything.i.name}}-{{anything.i.age}}</div>
   </template>
</my-list>
Deilan
  • 4,740
  • 3
  • 39
  • 52
Cagatay Civici
  • 6,406
  • 1
  • 29
  • 34
1

There was a question regarding this in the past (see Use content of component template in angular 2) and this doesn't seem to be supported.

There are two things here:

  • When you provide an input template for the component, your i is variable is evaluated against the current component and not my-list one. If you want to use its properties you must do something like that:

    <my-list #myList>
      <div>{{myList.i.name}}-{{myList.i.age}}</div> //user should be able to provide custom template like this
    </my-list>
    
  • The other problem is the ability to use ng-content within a loop and it's not supported. I think that we could add an issue for this...

Here is a the plunkr I used for my tests: https://plnkr.co/edit/a06vVP?p=preview.

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • this is perfect for properties but still we can't use custom template. can't we somehow get reference of content of template and clone it for ngFor like angular1? – Akhlesh Apr 10 '16 at 17:13
0

You can find a short interesting guide which shows you how to build such a list-component with custom-template here.

O.DO
  • 71
  • 1
  • 2