Reputation: 12660
I have two controls created using the ControlValueAccessor
interface - a date picker and an age selector - and would like to bind them together using the same value. These represent retirment date and age and the user should be able to modify one and see the other input update.
I have done this by subscribing to the form.valueChanges
observable, like this:
this.form.valueChanges.subscribe((val) => {
if (val.retirementDate !== this.currentDatePickerValue) {
// retirement date changed
this.currentDatePickerValue = val.retirementDate;
setTimeout(() => this.retirementAgeCtrl.setValue(this.currentDatePickerValue));
} else if (val.retirementAge !== this.currentAgePickerValue) {
// retirement age changed
this.currentAgePickerValue = val.retirementAge;
setTimeout(() => this.retirementDateCtrl.setValue(this.currentAgePickerValue));
}
});
Without the setTimeout()
s, this gives rise to a stack exception, but with them it works. Unfortunately it's not as efficient as it could be, since this code runs a dozen times or more when either of the inputs changes.
How can I accomplish this so that the code only executes as many times as necessary?
Upvotes: 0
Views: 345
Reputation: 12960
Pass emitEvent option as false
emitEvent: When true or not supplied (the default), both the statusChanges and valueChanges observables emit events with the latest status and value when the control value is updated. When false, no events are emitted.
this.form.valueChanges.subscribe((val) => {
if (val.retirementDate !== this.currentDatePickerValue) {
// retirement date changed
this.currentDatePickerValue = val.retirementDate;
this.retirementAgeCtrl.setValue(this.currentDatePickerValue, {emitEvent: false})
} else if (val.retirementAge !== this.currentAgePickerValue) {
// retirement age changed
this.currentAgePickerValue = val.retirementAge;
this.retirementDateCtrl.setValue(this.currentAgePickerValue, {emitEvent: false})
}
});
Upvotes: 1