You could use ngTemplateOutlet to achieve it.
Following are the steps in implementing dynamic repeater:
First step is to provide a TemplateRef
as a child element of the RepeaterComponent
:
<repeater [repeaterArray]="repeaterObj">
<ng-template>
...
</ng-template>
</repeater>
Second step is to query this template within RepeaterComponent
via @ContentChild
:
export class RepeaterComponent {
@ContentChild(TemplateRef) itemTemplate: TemplateRef<any>;
...
Third step is use ngTemplateOutlet
to render the template:
@Component({
selector: 'repeater',
template: `
<input type="button" value="Add" (click)="addRow()">
<div class="repeater" *ngFor="let row of repeaterArray">
<div class="repeaterRow">
<input type="button" value="Remove" (click)="removeRow(row.rowId)">
<ng-template <== this line
[ngTemplateOutlet]="itemTemplate"
[ngTemplateOutletContext]="{ $implicit: row }">
</ng-template>
</div>
</div>`
})
export class RepeaterComponent {
@Input() repeaterArray: Array<any>;
@ContentChild(TemplateRef) itemTemplate: TemplateRef<any>;
...
}
Fourth step is to use reference to the row
inside TemplateRef
within MasterComponent
(just back to our first step):
<repeater [repeaterArray]="repeaterObj">
<template let-row>
<field-textbox [data]="row.name" [label]="'Name'"></field-textbox>
<field-textbox [data]="row.description" [label]="'Description'"></field-textbox>
</template>
</repeater>
Notice: we are passing ngOutletContext
like object with $implicit
property.
using the key $implicit in the context object will set it’s value as
default.
It works as follows:
[ngTemplateOutletContext]="{ $implicit: row }" ==> <template let-row>
[ngTemplateOutletContext]="{ item: row }" ==> <template let-row="item">
ngOutletContext
is availlable only since Angular 2 version of 2.0.0-rc.2
You could try the corresponding plunkr (updated to 5.0.0)