I have a unique scenario where I need to create child components that need to get some information from my backend when they are created. My process flow is as follows:
1) parent component's template file has an *ngFor
that creates n number of child components
2) in the child component's creation directive I'm including two event emitters to listen on the parent (one for creation to add to an array, and one to remove)
3) when the child component is spun up, I gather what I need from my back end for that component, then use the creation event emitter from within ngOnInit()
to inform the parent that it's ready.
4) the parent then adds that child component to its array of children
5) from within the child component, there is a link to remove that child which emits that event up to the parent as well, the parent removes that instance from the array.
All of the above is working correctly but I also need to remove the actual HTML from the parent's template when the child passes up the remove event. I looked here: Dynamically ADDING and REMOVING Components in Angular and it's what I need but it's assuming that the child components are being generated in code, not in the template.
I assume I need to use something similar to that though and add my child component references to my @ViewChild
container but I don't see any methods on container
that allow me to AddFromTemplate()
etc.
Here is some code:
Parent Component (ts):
export class MatParentComponent implements OnInit {
constructor(private someService: SomeService) { }
@ViewChild('container', { read: ViewContainerRef, static: false }) container: ViewContainerRef;
// dunno how to use container in this example to add references to child components for removal from HTML later
matChildComponents: MatChildComponent[] = [];
addInstanceToCollection(matChildComponent: MatChildComponent): void {
this.matChildComponents.push(matChildComponent);
}
removeInstanceFromCollection(matChildComponent: MatChildComponent): void {
let i: number = 0;
for (let i = 0; i < this.matChildComponents.length; i++) {
if (this.matChildComponents[i] == matChildComponent) {
console.log(i);
this.matChildComponents.splice(i, 1);
break;
}
}
}
ngOnInit() {
}
}
and its corresponding template HTML:
<mat-child *ngFor="let instance of instances"
[someProp1]="instance.someProp1"
[someProp2]="instance.someProp2"
(instanceCreatedEmitter)="addInstanceToCollection($event)"
(instanceRemoveEmitter)="removeInstanceFromCollection($event)"></mat-child>
child component (ts):
export class MatChildComponent implements OnInit {
@Input() someProp1: string;
@Input() someProp2: string;
@Output() instanceCreatedEmitter = new EventEmitter<MatChildComponent>();
@Output() instanceRemoveEmitter = new EventEmitter<MatChildComponent>();
constructor() { }
removeThisComponent(): void {
this.instanceRemoveEmitter.emit(this);
}
ngOnInit() {
// do my stuff from back end to fully load up this component
this.componentLoaded = true;
// now emit this instance back to the parent so they can add it to their collection
this.instanceCreatedEmitter.emit(this);
}
}
should I be using this @ViewChild()
approach? Is there something else I can do? Could I remove the child component from its own implementation after I emit the removal event? IE: something like this.destroy()
.
TIA