自定义验证器参数不会对更改做出反应

时间:2018-11-05 08:56:55

标签: angular angular-reactive-forms

我有一个需要字符串参数的自定义验证器。但是,当我更改代码中的参数时,该参数不会更改表单初始化期间传递的初始值。我发现的唯一解决方法是删除验证器,然后使用新参数再次添加它。

这是期望的行为吗?我该如何强制angular来“重新加载”验证器参数?

Demo of unwanted behaviour.

代码:

HTML

<form [formGroup]="reactiveForm">
    <input type="text" formControlName="input">
  <button (click)="changeToB()" >switch to b</button>
<br>
  valid: {{reactiveForm.get('input').valid}}
  <br>
  shouldBeEqualTo: {{shouldBeEqualTo}}
</form>

TS

export class AppComponent {
  shouldBeEqualTo = 'a';
  reactiveForm: FormGroup;
  constructor(private fb: FormBuilder) {
    this.reactiveForm = this.fb.group({input: ['a', customValidator(this.shouldBeEqualTo)]})
  }

  changeToB(){
    this.shouldBeEqualTo = 'b';
  }
}

export function customValidator(equalTo: string): ValidatorFn{
 return (c: AbstractControl): { [key: string]: any } => {
   console.log(equalTo)
   console.log(c.value)
   if(c.value !== equalTo){
     return {valid: false};
   }
   return null;
 }
}

1 个答案:

答案 0 :(得分:1)

您可能需要向表单中添加自定义验证器,而不是表单控件,这样您才可以访问本地属性。

组件

  shouldBeEqualTo = 'a';
  reactiveForm: FormGroup;
  constructor(private fb: FormBuilder) {
    this.reactiveForm = this.fb.group({ input: ['a' ]},
                      {validator:this.getCustomeValidator()})
  }

  changeToB() {
    this.shouldBeEqualTo = 'b';
  }

  getCustomeValidator() {
    return (c: AbstractControl): { [key: string]: any } => {
      if (c.value !== this.shouldBeEqualTo) {
        return { valid: false };
      }
      return null;
    }
  }
}

demo

可以考虑使用另一种方法使验证器可重用,但我仍然建议第一个解决方案

export class AppComponent {
  shouldBeEqualTo = 'a';
  reactiveForm: FormGroup;
  constructor(private fb: FormBuilder) {
    this.reactiveForm = this.fb.group({input: ['a', customValidator(this,'shouldBeEqualTo')]})
  }

  changeToB(){
    this.shouldBeEqualTo = 'b';
  }
}

export function customValidator($this,property:string): ValidatorFn{
 return (c: AbstractControl): { [key: string]: any } => {
   if(c.value !== $this[property]){
     return {valid: false};
   }
   return null;
 }
}

demo

相关问题