I need to be able to completely reload a child component. It seems the best way to to acheive this is by using a simple *ngIf
with a boolean value; Set false to remove the component, and then set to true to re-initialize it, ie:
<app-child *ngIf="enabled"></app-child>
However, it seems that just doing this isn't enough to quickly remove/reinitialize the component:
reloadTree(){
this.enabled = false;
this.enabled = true; // doesn't work- child ngOnInit isn't called
}
Rather, I have to use a setTimeout
before it will work:
reloadTree(){
this.enabled = false;
const self = this;
setTimeout(function(){
self.enabled = true;
}, 1);
}
I presume this is to do with the way Angular renders templates? This isn't paricularly elegant- can anyone suggest a better way to acheive what I'm trying to do here? Thanks
So just for the record and without trying to argue if it's a clean way to do it or not, here's how you can work around the problem with the flag toggling. The main idea is to destroy the child component and create it again afterwards, which you can do with a simple *ngIf flag on the child component.
If the flag is toggled to false, the child component is destroyed and completely removed from the DOM. Afterwards you can set it to true again to create a new instance (if I'm not mistaken here).
The problem in the given code and the need for the workaround with the setTimeout
method is that angular needs to be aware of changes to react to them. In this case the toggle in two lines of code may be just too quick for angular to even get hold of a change (or maybe the compiler even removes the first line at all, so nothing is ever changed, not sure though), therefore the component is neither removed nor is a new instance created.
reloadTree(){
this.enabled = false; // switching to false
this.enabled = true; // and back to true
// this does not notify angular that something has actually changed
}
What we need to do is to manually tell angular that a value has changed. This can be done through angulars ChangeDetectionRef class, which can be injected into the component. In between toggling the enabled
flag, we notify angular to look for changes, so it can react to that by removing the component completely. Then we can set it back to true to create a new instance.
constructor(private changeDetector: ChangeDetectorRef){}
reloadTree(){
this.enabled = false;
// now notify angular to check for updates
this.changeDetector.detectChanges();
// change detection should remove the component now
// then we can enable it again to create a new instance
this.enabled = true;
}
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