Search code examples
angularlistangular2-templatechildrenngfor

Reusable list of custom components in Angular


I want to create reusable SortedList Component in Angular5. The list should accept any array of listItems (objects) as attribute. From ListContainer component I want to use the list and pass a list item template as follows:

<div class='list-container'>
<SortedList [items]='getListItems()' [categories]='getSortCategories()' >
  <ACustomItem [item]='item'></AcustomItem>
</SortedList
<div>

ACustomItem will be any component that accepts [item], the html will vary depends on implementation.

Inside my SortList I have:

<div class='sorted-list'>
  <div class='sorted-list__header'>
    <div class='sorted-list__header-title'>{{title}}</div>
    <select [(ngModel)]='selectedCategory' (ngModelChange)='onCategoryChange($event)'>
      <option *ngFor='let category of categories' [ngValue]='category.id'>{{category.name}}</option>
    </select>
  </div>
  <div class='sorted-list__body'>
    <div *ngFor="let item of data | orderBy: selectedCategory.id ">
     <ng-content></ng-content>
    </div>
  </div>
</div>

Above does not work, what is missing here? I assume I need to use ng-template here but not sure how it should be embedded here?


Solution

  • I found this solution and modified it for Angular 5 and your specific components. As ngOutletContext was removed from version 5 of Angular here is an example in stackblitz.

    SortedList component template

    <div *ngFor="let item of items">
        <template [ngTemplateOutletContext]='{item: item}' [ngTemplateOutlet]="templateVariable"></template>
    </div>
    

    SortedList component ts

    @Input() items: any[];
    @ContentChild(TemplateRef) templateVariable: TemplateRef<any>;
    

    App component template

    <app-sorted-list [items]="myItems">
        <ng-template let-item="item">
            <!--Here can be any component-->
            <app-sorted-list-item [item]="item"></app-sorted-list-item>
        </ng-template> 
    </app-sorted-list>