I want to delete child component, parent will delete the last child only and after that, it shows that index is -1 from hostView and can't delete the child from view
this is my Child View
<button (click)="remove_me()" >I am a Child {{unique_key}}, click to Remove
</button>
this is my Child Component
import { Component } from '@angular/core';
import { ParentComponent } from '../parent/parent.component';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
})
export class ChildComponent {
public unique_key: number;
public parentRef: ParentComponent;
constructor() {}
remove_me() {
console.log(this.unique_key);
this.parentRef.remove(this.unique_key);
}
}
this is my Parent View
<button type="button" (click)="AddChild()">
I am Parent, Click to create Child
</button>
<div>
<ng-template #viewContainerRef></ng-template>
</div>
this is my Parent Component
import {
ComponentRef,
ViewContainerRef,
ViewChild,
Component,
} from '@angular/core';
import { ChildComponent } from '../child/child.component';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css'],
})
export class ParentComponent {
@ViewChild('viewContainerRef', { read: ViewContainerRef })
vcr!: ViewContainerRef;
ref!: ComponentRef<ChildComponent>;
child_unique_key: number = 0;
componentsReferences = Array<ComponentRef<ChildComponent>>();
constructor() {}
AddChild() {
this.ref = this.vcr.createComponent(ChildComponent);
let childComponent = this.ref.instance;
childComponent.unique_key = this.child_unique_key;
childComponent.parentRef = this;
}
remove(key: number) {
const index = this.vcr.indexOf(this.ref.hostView);
console.log(index);
if (index != -1) {
this.vcr.remove(index);
}
// removing component from the list
this.componentsReferences = this.componentsReferences.filter(
(x) => x.instance.unique_key !== key
);
}
}
I tried the methods from older Angular versions that supports ComponentFactoryResolver, but I want to upgrade the version of Angular
CodePudding user response:
There are some obvious errors in your code:
- You initialize a property
componentsReferences = Array<ComponentRef<ChildComponent>>();
but never populate it. - even if you filter out that element from that list you dont remove it from the view-container. Which is why angular wont remove the component. (https://angular.io/guide/dynamic-component-loader)
But I have to say that there are quite some more issues with your code. You should never ever have a ref from your child-component to your parent component for example.
I suggest you have a look at and follow through with the angular tour of heros because dynamic component creation is quite a complex topic and it seems that you should stick to some basics first.
For example could your desired outcome be done kinda like this:
export class ParentComponent {
uniqueKeys: number [] = [];
private counter = 0;
addKey() {
this.uniqueKeys.push(this.counter);
this.counter ;
}
removeLastKey() {
this.uniqueKeys.pop();
}
}
in parent-component.html:
<app-child *ngFor="let key of uniqueKeys" [key]=key></app-child>
and in child-component.html you can have your @Input() for the key property if needed... Just check https://angular.io/tutorial
CodePudding user response:
To remove a child component in Angular, you can use the ViewContainerRef
class. In your ParentComponent
, you can inject ViewContainerRef
in the constructor and use its remove()
method to remove the child component. The remove()
method takes the index of the child component in the view container as its argument. You can use the indexOf()
method to get the index of the child component.
Here is an example of how you can use ViewContainerRef
to remove a child component in Angular:
import { ViewContainerRef } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css'],
})
export class ParentComponent {
@ViewChild('viewContainerRef', { read: ViewContainerRef })
vcr!: ViewContainerRef;
constructor(private vcRef: ViewContainerRef) {}
remove() {
const index = this.vcr.indexOf(this.ref.hostView);
if (index != -1) {
this.vcr.remove(index);
}
}
}
In the remove()
method, you can use the indexOf()
method to get the index of the child component in the view container and then use the remove()
method to remove the child component from the view container.
You can then call the remove()
method from the child component when the user clicks the button to remove the child component.
Here is an example of how you can call the remove()
method from the child component:
import { Component } from '@angular/core';
import { ParentComponent } from '../parent/parent.component';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
public unique_key: number;
public parentRef: ParentComponent;
constructor() {
}
remove_me() {
console.log(this.unique_key)
this.parentRef.remove();
}
}
In the remove_me()
method, you can call the remove()
method on the parentRef property to remove the child component.
I hope this helps!