I would like to create a component which takes another one in parameter, and generate a collection of instances of this component.
(The objective in the end is to create a generic backoffice).
For example, with something like that :
<common-collection [component]="collectionDisplayComponent" [items]="items"></common-collection>
I would get this (here the component is a loader for test purpose) :
So I already have something working (almost): Here the code of the component :
@Component({
selector: 'common-collection',
templateUrl: 'collection.component.html',
styleUrls: ['collection.component.css'],
providers: [ ]
})
export class CollectionComponent implements AfterViewInit{
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
@Input()
set items(items: Array<object>){
this._items = items;
this.refresh();
}
private _items: Array<object> = [];screen
@ViewChildren('componentRef', {read: ViewContainerRef}) public widgetTargets: QueryList<ViewContainerRef>
public refresh() {
let component = LoaderComponent; // Should be given in parameter, set manually for now
if(typeof(this.widgetTargets) !== "undefined"){
for (let i = 0; i < this.widgetTargets.toArray().length; i++) {
let target = this.widgetTargets.toArray()[i];
let widgetComponent = this.componentFactoryResolver.resolveComponentFactory(component);
let cmpRef: any = target.createComponent(widgetComponent);
}
}
}
ngAfterViewInit(): void {
this.widgetTargets.changes.subscribe(() => {
this.refresh()
});
}
}
And the template code associated :
<div id="div-container">
<div fxLayout="row" fxLayoutWrap fxLayoutGap="1%" fxFlexAlign="center center">
<div class="div-item-card" fxFlex="24" *ngFor="let item of _items;">
<div #componentRef></div>
</div>
</div>
</div>
This code works, but the problem is that I'm setting the viewChildren at the wrong time, because I have this error :
I think I should fill the widgetTargets variable and do the ngFor on it instead of _items, but I don't find any example to add components directly in it.
All the examples consist in creating "void" dom elements, and setting them with the component factory after that (which I do there and causes the error).
Thanks a lot for your help.
EDIT : The "items" variable is set after the component init : it is loaded from an async call to a database in a parent component.
EDIT2 Working with something like this in a refresh method.
for (let i = 0; i < this.widgetTargets.toArray().length; i++) {
let target = this.widgetTargets.toArray()[i];
let widgetComponent = this.componentFactoryResolver.resolveComponentFactory(component);
target.clear();
let cmpRef: any = target.createComponent(widgetComponent);
cmpRef.instance.value = this._items[i]["value"];
this.cd.detectChanges();
}

