I am creating a page which is like a form creator. The user will click and add different components into the page, which will add entries into the "component" variable as so:
Example for Component1:
const childComponent = this.componentFactoryResolver.resolveComponentFactory(Component1);
this.components.push(childComponent);
So the components array will have a collection of ComponentFactory elements.
I am then creating components dynamically and conditionally in HTML as follows:
<div cdkDropList class="example-list" style="margin: 20px" (cdkDropListDropped)="drop($event)">
<div cdkDrag *ngFor="let cmp of components">
<ng-container *ngIf="cmp.componentType.name=='Component1'">
<app-Component1></app-Component1>
</ng-container>
<ng-container *ngIf="cmp.componentType.name=='Component2'">
<app-Component2></app-Component2>
</ng-container>
<ng-container *ngIf="cmp.componentType.name=='Component3'">
<app-Component3></app-Component3>
</ng-container>
</div>
</div>
Works fine so far. Now, when the user clicks the save button, it should get a list of all the components on the page. I need it in the end as the components are editable, so the values will change. the list "components" cannot be used as it only contains the Factory elements.
Is it possible to get the component instance that gets declared in HTML? I am trying @ViewChildren, but I might need to add it for every component type, so I wont get it in the order it was added by the user.
Finally, I have tried to create the component in code and then add it to the page using ComponetFactoryResolver. However, each of them needs to have the directive "cdkDrag" declared within it, which becomes impossible using that approach.
Thanks.
When using a loop, the template reference variables can refer to several items.
This is shown in this stackblitz and as you can see, both elements have the correct class instance.
Hope this helps !
<ng-container *ngFor="let i of [0, 1]; last as isLast; first as isFirst">
<hello *ngIf="isFirst" #child name="{{ name }}"></hello>
<goodbye *ngIf="isLast" #child name="{{ name }}"></goodbye>
</ng-container>
<p>
Start editing to see some magic happen :)
</p>
import { Component, ViewChildren, QueryList } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
@ViewChildren('child') children: QueryList<any>;
ngOnInit() {
setTimeout(() => console.log(this.children.first), 1000);
setTimeout(() => console.log(this.children.last), 1000);
}
}
HelloComponent
name: "Angular"
__proto__: Object
GoodbyeComponent
name: "Angular"
__proto__: Object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With