Problem
I’m trying to dynamically load multiple instances of the same component, with a new component being added/loaded to the screen when a user submits a form. The idea behind this is that a user can provide details on the form that is then displayed on that particular instance of that component that is created.
My initial idea was to have some sort of data structure such as an array or map for key pair values, whereby I could add a new instance of my component alongside the form data to my data structure when the user submits the form. Then angular could somehow display every instance of a component that resides in the data structure like the following image below:
It’s important to note that the form is actually its own separate component that’s in the form of modal dialog. This form dialog is opened when the green Add Status Box button is pressed, then the user can submit the form and (hopefully) be able to create a new instance of the status box component with the data provided from the submitted form.
However this is proving difficult, currently the way I’m achieving this in the screenshot above is by merely displaying each component individually in the app.component.html, which isn’t dynamic at all and has no user control:
<app-header></app-header>
<div class='status-box-container'>
<app-status-box></app-status-box> //component I’m trying to display
<app-status-box></app-status-box> //component I’m trying to display
<app-status-box></app-status-box> //component I’m trying to display
</div>
Things I’ve tried
I’ve followed a few tutorials already but either the outcome of the said tutorial doesn’t quite do what I’m asking, doesn’t work at all or it’s too complicated for me to understand.
First I tried to follow this official guide from the Angular website but this only displays one component at a time and dynamically changes its content every 3 seconds rather than displaying multiple instances of one component at the same time.
Next, I tried to follow this stackblitz from this existing stack overflow question, but I found this to not work and to be very complicated, most of which I didn’t understand. Although it’s quite close to what I’m trying to achieve.
Lastly, I tried to follow this stackblitz I found, but it’s not as dynamic as I want it to be because each instance of the component is hardcoded into different variables, I also couldn't get it to work.
Observations
One thing I have noticed though is that all three approaches have two parts in common. Firstly in the app.component.html they either use <ng-container #messageContainer></ng-container>
or <ng-template #messageContainer></ng-template>
. To my understanding, this is where the dynamic components would be loaded into the html template.
The second part in app.component.ts usually looks something like this:
@ViewChild('messageContainer', { read: ViewContainerRef, static: true })
messageContainer: ViewContainerRef;
constructor (private cfr: ComponentFactoryResolver) { }
private createComponent (compClass)
{
const compFactory = this.cfr.resolveComponentFactory(compClass);
return this.messageContainer.createComponent(compFactory);;
}
private loadNewComponentList ()
{
this.messages.forEach((msg, idx) =>
{
this.destroyCompFromList(this.componentList[idx]);
const comp = this.createComponent(componentMap[this._crtComp]);
(comp.instance as any).message = msg;
comp.changeDetectorRef.detectChanges();
this.componentList[idx] = comp;
});
}
This is taken from the first tutorial I tried.
Now I don’t really understand what this code does, but from looking at it, it seems as though the ComponentFactoryResolver
would be responsible for creating multiple instances of identical components. And the ViewContainerRef
seems to be what’s used in the html template.
This seems to be the direction I should head in but I don’t understand what these imported classes do, and I’m not even sure if this approach would be suitable for my specific requirements.
I was hoping someone could show me a simple solution to this problem, or at least adapt/simplify the tutorials to meet my specific requirements.
Thanks.
See Question&Answers more detail:
os