Reputation: 737
I have 3 fields linked with forms which type is number, when I modify field A, it modifies field B and C, when I modify field B it modifies field A and C and when I modify field C it modifies field A and B accordingly.
my component is as below :
this.form= this.formBuilder.group({
fieldA: new FormControl(this.valueA),
fieldB: new FormControl(this.valueB),
fieldC: new FormControl(this.valueC),
});
onFieldAchanged() {
//Do some calculs
this.form.get('fieldB').setValue(x);
this.form.get('fieldC').setValue(y);
}
onFieldBchanged() {
//Do some calculs
this.form.get('fieldA').setValue(x);
this.form.get('fieldC').setValue(y);
}
onFieldCchanged() {
//Do some calculs
this.form.get('fieldA').setValue(x);
this.form.get('fieldB').setValue(y);
}
and my template as below :
<input formControlName="fieldA" type="number" class="form-control" (ngModelChange)="onFieldAchanged()"/>
<input formControlName="fieldB" type="number" class="form-control" (ngModelChange)="onFieldBchanged()"/>
<input formControlName="fieldC" type="number" class="form-control" (ngModelChange)="onFieldCchanged()"/>
The problems come when you modify one of the field, it goes into a loop and makes the app crash.
I already tried to add the parameter emitEvent: false
in my setValue()
but it changed nothing
So my question: Is there a way to prevent the triggering of the other functions ? When I modify fieldA
I just want to enter in my onFieldAchanged()
function and set the two others values, no more.
Thank you for your help
Upvotes: 2
Views: 6927
Reputation: 29335
there sure is:
first, instead of using (ngModelChange)
, use valueChanges
observable:
this.form.get('fieldA').valueChanges.subscribe(v => this.onFieldAchanged());
this.form.get('fieldB').valueChanges.subscribe(v => this.onFieldBchanged());
this.form.get('fieldC').valueChanges.subscribe(v => this.onFieldCchanged());
then, add the emitEvent
option into your setValue
fuctions to stop their valueChanges
from emitting:
onFieldAchanged() {
//Do some calculs
this.form.get('fieldB').setValue(x, {emitEvent: false});
this.form.get('fieldC').setValue(y, {emitEvent: false});
}
the issue is mixing ngModel
with reactive forms. gotta choose one.
Upvotes: 14
Reputation: 433
You can easily pass a parameter in your onFieldXchanged() function in the template and check for this string to see if the event was triggered from an input being typed or from one of the other eventriggers. Just make a guard.
Upvotes: 0
Reputation: 1229
Weird, I actually did something similar to this myself:
What I did was make two form groups:
this.groupA = this.formBuilder.group({
fieldA: new FormControl(''),
});
this.groupB = this.formBuilder.group({
fieldB: new FormControl(''),
});
Then I have it set that fieldA's value changes causes fieldB's value to change:
ngOnInit(){
this.groupA.get('fieldA').valueChanges.subscribe(val => {
this.groupB.get('fieldB').setValue(val);
});
}
Then in my template, fieldA's value is set to fieldB's to complete the sync:
<input matInput placeholder="Field A:" formControlName="fieldA [value]="groupB.get('fieldB').value">
Upvotes: -1