在Angular中停止无限循环反应形式控件更新

时间:2019-04-12 05:51:18

标签: angular rxjs angular-reactive-forms

我在表单上有2个输入,一个数字输入称为“ ageMonths”,一个日期选择器称为“ dateOfBirth”。

我希望用户能够输入年龄的月份,或者使用日期选择器选择出生日期(出生日期)。如果他们从日期选择器中输入一个Dob,我希望month字段更新为以月为单位的年龄。如果他们输入以月为单位的年龄,我希望日期选择器跳到该日期。我正在使用反应形式。

我添加了一个类级变量来保存一个切换开关,每次更改任一控件的值时都会读取并设置该切换开关。但是,由于事件未按我期望的顺序触发,因此我认为这不能按预期进行。

我需要做些什么才能使它起作用?

我的代码是:

ignoreDateUpdate = false;
form: FormGroup;
...
constructor(...){
this.form = new FormGroup({
    dateOfBirth: new FormControl({ value: new Date()}),
    ageMonths: new FormControl({ value: 0 }),
    ...
});
...
this.form.get('ageMonths').valueChanges.subscribe(
m => {
    if (ignoreDateUpdates) {return};
    ignoreDateUpdates = true;
    <code to set DateSelectorValue>
    ignoreDateUpdates = false;
    });
this.form.get('dateOfBirth').valueChanges.subscribe(
dob => {
    if (ignoreDateUpdates) {return};
    ignoreDateUpdates = true;
    <code to set MonthsInput>
    ignoreDateUpdates = false;
});
}

3 个答案:

答案 0 :(得分:0)

我正在回答这个问题,因为我已经通过将{emitEvent: false}选项添加到setValue调用中来实现了所需的行为:

const calcDate = <calculate date from months value>;
this.form.get('dateOfBirth').setValue(calcDate, { emitEvent: false });

但是我仍然想知道,如果有人可以解释,为什么切换字段没有按预期工作?

答案 1 :(得分:0)

您在错误的时间将标志设置为false,因此它什么也不做。您几乎立即将其设置为true,然后设置为false。当第二个窗体控件获取值更改时,它将始终为false。

执行此操作(对于两个控件):

this.form.get('dateOfBirth').valueChanges.subscribe(
  dob => {
      if (ignoreDateUpdates) {
        ignoreDateUpdates = false;
        return;
      };
      ignoreDateUpdates = true;
      <code to set MonthsInput>
  });

答案 2 :(得分:0)

我也在我的应用程序中实现了这种功能,我有两个输入框,一个是小时,第二个是分钟,每当用户以小时为单位输入值时,当用户以分钟为单位输入时,我将小时转换为分钟并更新分钟输入框输入框,然后我将分钟转换为小时并更新小时输入框。

private  ignoreDateUpdates=true;        
this.form.get('ageMonths').valueChanges.subscribe(m => {
        if (ignoreDateUpdates) {
        ignoreDateUpdates = false;
        <code to set DateSelectorValue>
         }
        else{
      ignoreDateUpdates = true;
         }       
 });
    this.form.get('dateOfBirth').valueChanges.subscribe(
    dob => {
        if (ignoreDateUpdates) {
        ignoreDateUpdates = false;
        <code to set MonthsInput>
       }
        else{
        ignoreDateUpdates = true;
      }    
});
    }