I've created a dynamic component that I can inject templates to it from the outside. My goal is to be able to inject any template, duplicate those templates inside the component and 2 way data bind to it in order to get data changes.
It looks something like that:
@Component({
selector: 'app-custom-container',
templateUrl: './custom-container.component.html',
styleUrls: ['./custom-container.component.css']
})
export class CustomContainerComponent implements OnInit {
@Input() template: TemplateRef<any>;
@Input() addButtonLabel: string;
templates: Array<TemplateRef<any>> = [];
constructor() { }
ngOnInit() {
this.templates.push(this.template);
}
}
The HTML,I have an add button
button to add more templates to itself dynamically and I have a trash button
to delete templates:
<ng-container *ngFor="let template of templates; let index = index; let last = last;">
<button type="button" (click)="templates.splice(index, 1);" class="trash-button"></button>
<ng-container *ngTemplateOutlet="template; context:{index:index}"></ng-container>
</ng-container>
<div (click)="templates.push(template)" class="add-button">{{addButtonLabel}}</div>
I use this component like this:
<app-custom-container" [template]="tpl" addButtonLabel="ADD TEMPLATE" addButtonClass="add-butto"></app-custom-container>
<ng-template #tpl let-index="index">
<p-dropdown [options]="mylist" [autoWidth]="false" [(ngModel)]="myData[index]" name="myName{{index}}"
required>
</p-dropdown>
</ng-template>
I'm using ng-prime, thus the p-dropdown
.
So what I would want is to be able to create those dynamic components, inject any template to it and be able to duplicate this template withing this dynamic component. In addition, I would want the selected data from the drop down to be inserted to my data, thus the ngModel
.
Problems I have:
- I am not sure that this is the best design for my goals. The
index
that is communicated back, seems pretty awkward to me. - Basically it is working, except for the
splice
part. When I'msplice
ing, the data model gets new indexes after thecontainer
is being rendered again and everything is a mess, the data doesn'tsit
s where it should. I thought about sending the data as well and have the component manage it, but I'm not sure that it's the right thing to do or even how to do it.
I would appreciate your advise and add info if something is not clear.
Update 1: Add plnkr.
As you can see, I'm adding elements and when I try to delete them, it deletes from the bottom. I must know if my basic approach is good and then to figure how to delete and update my data array accordingly.