使用共享formcontrol进行Angular2反应性交叉字段验证

时间:2017-02-07 21:28:05

标签: forms validation angular

我尝试了很多方法来实现用例,但解决方案都没有成功。

我想要实现的是(使用angular2中的反应形式)一个带有两个交叉字段验证的表单:

  • 验证A&乙
  • 验证B& ç

我尝试创建两个FormGroups,其中引用了A& A; B和B& C FormControls。每个FormGroup都有自己的验证器,只验证它的子节点。它不起作用,因为共享FormControl是问题:当值更改时,只有一个验证器触发。

首先尝试:

this.controlA = new FormControl();
this.controlB = new FormControl();
this.controlC = new FormControl();

this.form = new FormGroup({
ab: new FormGroup({
 controlA: this.controlA,
 controlB: this.controlB
}, this.validateAB ),
bc: new FormGroup({
 controlB: this.controlB,
 controlC: this.controlC
}, this.validateBC);

// Validators methods returns a ValidatorFn (which returns null if everything fine or an error object, if validation fails)

无效。

尝试2:

this.controlA = new FormControl();
this.controlB = new FormControl();
this.controlC = new FormControl();

this.form = new FormGroup({
ab: new FormGroup({
 controlA: this.controlA,
 controlB: this.controlB
}),
bc: new FormGroup({
 controlB: this.controlB,
 controlC: this.controlC
});


this.setABValidator(<FormGroup>this.form.get('ab'));
this.setBCValidator(<FormGroup>this.form.get('bc'));

// similar für setBCValidator which triggers this.validateBC(form)
private setABValidator(form: FormGroup): void {
    if (form) {
      const aCtrl = form.get('controlA');
      const bCtrl = form.get('controlB');
      if (aCtrl && bCtrl ) {
        aCtrl.valueChanges.subscribe((value: any) => {
          this.validateAB(form);
        });
        bCtrl.valueChanges.subscribe((value: any) => {
          this.validateAB(form);
        });
      }
    }
  }

  private validateAB(formGroup: FormGroup): void {
    const aCtrl = formGroup.get('controlA');
    const bCtrl = formGroup.get('controlB');
    const errorKey = 'ERR.AB';
    if (aCtrl && bCtrl ) {
      if (condition fails) {
        ThisCLass.setValidationError(aCtrl , errorKey);
        ThisCLass.setValidationError(bCtrl , errorKey);
      } else {
        ThisCLass.removeValidationError(aCtrl, errorKey);
        ThisCLass.removeValidationError(bCtrl, errorKey);
        formGroup.updateValueAndValidity();
      }
    }
  }

它的作品,但表格的整体有效性是不正确的。 你觉得它有可能以一种很好的方式吗?

1 个答案:

答案 0 :(得分:0)

我不明白为什么你需要两个表格组。只使用一个合并两种验证的方法吗?

这应该做的工作:

this.form = new FormGroup({
 controlA: this.controlA,
 controlB: this.controlB,
 controlC: this.controlC
}, Validators.compose([this.validateAB, this.validateBC]);