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?
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With