7

I am trying to create a component that will do some stuff and loop over a result set. I want to be able to provide a "template" for the items in the looped result set.

For instance, this is kind of the idea I am going for:

<search-field> <ng-template let-item> <span><strong>{{item.foo}}</strong></span> <span>{{item.bar}}</span> </ng-template> </search-field> 

The content within the search-field component should be used as a template for each iteration of the looped result set within that component.

This is how the search-field component may look:

<div class="search-container"> <div class="search-input"> <input type="text" class="form-control" placeholder="Search users..." [(ngModel)]="searchString" (ngModelChange)="searchStringChanged($event)"> <div class="md-icon">search</div> </div> <ul class="search-results" *ngIf="searchResults.length > 0"> <li class="search-results__item" *ngFor="let result of searchResults"> <ng-content [item]="item"></ng-content> <!-- Template should be used here on each iteration and allow to pass in "item" to use in example up above --> </li> </ul> </div> 

How can I pass each item of the loop to the ng-content so that I have access to it in the code of the first example?

1 Answer 1

16

Solved this with the following:

Component template usage:

<search-field> <ng-template let-item> <span><strong>{{item.username}}</strong></span> <span>{{item.email}}</span> </ng-template> </search-field> 

Component template definition:

<div class="search-container"> <div class="search-input"> <input type="text" class="form-control" placeholder="Search users..." [(ngModel)]="searchString" (ngModelChange)="searchStringChanged($event)"> <div class="md-icon">search</div> </div> <ul class="search-results" *ngIf="searchResults.length > 0"> <li class="search-results__item" *ngFor="let item of searchResults"> <ng-template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{$implicit: item}"></ng-template> </li> </ul> </div> 

Component class:

@Component({...}) export class SearchFieldComponent { @ContentChild(TemplateRef) templateRef: TemplateRef<any>; // ... } 

The explanation:

Using ng-template, I can use the let-item syntax, where item is the data that will be passed into the template on each iteration of the loop.

And in order to make the above possible, in the search-field component I use ng-template with ngTemplateOutlet as the template reference, and ngTemplateOutletContext is given the value {$implicit: item}, where item is the data I want to pass into the template.

Lastly, in the component class I need to use ContentChild to get the reference to the template to use in the ngTemplateOutlet.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! This approach solves also nested custom components

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.