What I'm trying to achieve is a generic component that is bound to an array of arbitrary objects that allows adding and removing rows dynamically when the view of each row is also arbitrarily defined with components by a master component that uses it.
Note that MasterComponent
is an arbitrary component that would be implemented for different pages and is intended to be self contained and not defined by any metadata or external source.
What I have so far are the following Components:
RepeaterComponent 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-content select="row"></ng-content>
</div>
</div>
MasterComponent template:
<repeater [repeaterArray]="repeaterObj">
<row>
<field-textbox [data]="row.name" [label]="'Name'"></field-textbox>
<field-textbox [data]="row.description" [label]="'Description'"></field-textbox>
</row>
</repeater>
The <field-textbox>
component is a custom component that I use to encapsulate simple inputs that holds some additional data that I need to use.
The MasterComponent holds an object that for this instance looks like this:
repeaterObj = [
{
"rowId": 1,
"name": "First brand",
"description": "First description"
},
{
"rowId": 2,
"name": "Second brand",
"description": "Second description"
},
{
"rowId": 3,
"name": "Third brand",
"description": "Third description"
}
];
This approach has two issues that I can't seem to find a solution for.
- The
ng-content
selector is identical for all the rows when thengFor
duplicates the template which leaves me with only oneng-content
transclusion point after rendering. - There is no reference to the
row
variable from thengFor
declaration in the<field-textbox>
transcluded directives so I can't bind the data correctly.
Is there a better approach to implement the RepeaterComponent
that would give me the least amount of effort to create more new MasterComponents
of different arbitrary structures and different templates?
<input>
binding works as intended and also updates the object bound but changing the <field-textbox> textbox does not apply the binding back to the object. – Neocene