Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular6 - ngIf does not destroy object

I have a parent component that will change the child's form that is passed as @Input() when a button is clicked. I use ngIf to render the child component, but when I click to change the form, the child component does not get destroyed and recreated.

parent.component.ts

form: FormGroup;
showChildForm: boolean;
num: number;

ngOnInit(){ 
   this.showChildForm = false; 
   this.num = 1;
   this.form = new FormGroup({group:{'name', new FormControl('name'+this.num,[])}})
}

changeForm(){
   this.num += 1;
   this.showChildForm = true; 
   this.form = new FormGroup({group:{'name', new FormControl('name'+this.num,[])}})
}

parent.component.html

<button (click)="changeForm()"></button>
<child *ngIf="showChildForm" [form]="form"></child>

child.component.ts

@Input() form: FormGroup;

child.component.html

<form [formGroup]="form">
   <input type="text" [formControl]="form.get('name')"/>
</form>
like image 368
matchifang Avatar asked Mar 27 '26 11:03

matchifang


2 Answers

Inside changeForm you are not setting this.showChildForm to false again.

Try doing this:

changeForm(){
  this.num += 1;
  this.showChildForm = false; 
  setTimeout(() => {
    this.showChildForm = true; 
    this.form = new FormGroup({group:{'name', new FormControl('name'+this.num,[])}})
  })
}

toggling it off and then back on again in the next tick cycle (using setTimeout) will cause the component to be destroyed and recreated.

like image 113
danday74 Avatar answered Mar 29 '26 06:03

danday74


I had similar problem. In my opinion using changeDetector is more elegant than setTimeout

constructor(private changeDetector: ChangeDetectorRef){}

changeForm() {
    this.num += 1;
    this.showChildForm = 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.showChildForm = true; 
    this.form = new FormGroup({group:{'name', new FormControl('name'+this.num,[])}})
}
like image 28
DiPix Avatar answered Mar 29 '26 06:03

DiPix