I have created a simple example to demonstrate a weird issue I'm facing.
Stackblitz - https://stackblitz.com/edit/angular-change-detection-form-group
I have three components and here are they:
1 - app component
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'my-app',
template: `<hello [form]="form"></hello>
<hr />
<button (click)="changeFormValue()">Change Form Value</button>`,
styleUrls: ['./app.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent implements OnInit {
name = 'Angular';
form: FormGroup;
ngOnInit() {
this.form = new FormGroup({
name: new FormControl('ABC'),
age: new FormControl('24')
});
}
changeFormValue() {
this.form.setValue({
name: 'XYZ',
age: 35
})
}
}
2 - hello component
import { Component, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'hello',
template: `<form [formGroup]="form">
<app-input [form]="form"></app-input>
</form>`,
styles: [``],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class HelloComponent implements OnChanges {
@Input() form: FormGroup;
ngOnChanges(changes) {
console.log(changes)
}
}
3 - input component
import { Component, Input, OnInit, OnChanges, ChangeDetectionStrategy } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'app-input',
template: `Name : <input type="text" [formControl]="nameFormcontrol" /> {{nameFormcontrol.value}} <br /><br />
Age : <input type="text" [formControl]="ageFormcontrol" /> {{ageFormcontrol.value}}`,
styles: [``],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class InputComponent implements OnInit, OnChanges {
@Input() form: FormGroup;
nameFormcontrol;
ageFormcontrol;
ngOnInit() {
this.nameFormcontrol = this.form.get('name');
this.ageFormcontrol = this.form.get('age');
}
ngOnChanges(changes) {
console.log(changes)
}
}
In both hello component and input component, I have set the changedetection strategy to onpush. As you see above I am creating a form group instance in the app component and passing that to the child components. Now when I click on the button on app component to change the form value, it changes the value in the input fields but not the plain texts. It only works if I delete the on push change detection from both the child components. Even the ngOnChanges does not get called even if the formgroup values are changing.
Is n't it weird. How the change detection works for inputs and not for the plain texts here?
Could someone explain me this please? And what is the workaround of it without removing the onpush change detection.
See Question&Answers more detail:
os