Forms 共享formcontrol的Angular2反应性跨场验证

Forms 共享formcontrol的Angular2反应性跨场验证,forms,validation,angular,Forms,Validation,Angular,我尝试了很多方法来实现这个用例,但是没有一个解决方案成功 我试图实现的是(使用angular2中的反应式表单)一个具有两个跨域验证的表单: A&B的验证 B&C的验证 我尝试创建两个FormGroup,其中引用了A&B和B&C FormControls。每个FormGroup都有自己的验证器,它只验证它的子项。它不起作用,因为问题在于共享FormControl:当值更改时,只会触发一个验证器 第一次尝试: this.controlA = new FormControl(); this.con

我尝试了很多方法来实现这个用例,但是没有一个解决方案成功

我试图实现的是(使用angular2中的反应式表单)一个具有两个跨域验证的表单:

  • A&B的验证
  • B&C的验证
我尝试创建两个FormGroup,其中引用了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();
      }
    }
  }
this.controlA=newformcontrol();
this.controlB=新表单控件();
this.controlC=新表单控件();
this.form=new FormGroup({
ab:新表单组({
controlA:这个,controlA,
控制B:这个
}),
卑诗省:新形式集团({
控制B:这个,控制B,
controlC:这个
});
this.setABValidator(this.form.get('ab'));
this.setBCValidator(this.form.get('bc'));
//类似的für setBCValidator触发此。validateBC(表单)
私有setABValidator(表单:FormGroup):无效{
如有需要(表格){
const aCtrl=form.get('controlA');
const bCtrl=form.get('controlB');
如果(aCtrl和bCtrl){
aCtrl.valueChanges.subscribe((值:任意)=>{
这是一份有效的表格;
});
bCtrl.valueChanges.subscribe((值:any)=>{
这是一份有效的表格;
});
}
}
}
私有ValidateB(formGroup:formGroup):无效{
const aCtrl=formGroup.get('controlA');
const bCtrl=formGroup.get('controlB');
常量errorKey='ERR.AB';
如果(aCtrl和bCtrl){
如果(条件失败){
ThisCLass.setValidationError(aCtrl,errorKey);
ThisCLass.setValidationError(bCtrl,errorKey);
}否则{
ThisCLass.removeValidationError(aCtrl,errorKey);
ThisCLass.removeValidationError(bCtrl,errorKey);
formGroup.updateValueAndValidity();
}
}
}
它的作品,但形式的整体有效性是不正确的。
你认为这有可能吗?

我不明白你为什么需要两个表单组。只需使用一个合并两个验证的表单组即可

这应该可以做到:

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

我不明白为什么您需要两个表单组。只需使用一个合并两个验证的表单组

这应该可以做到:

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

添加一些代码以查看情况!我添加了两种不适用于我的用例的方法添加一些代码以查看情况!我添加了两种不适用于我的用例的方法在这个小案例中没有问题,但是如果我有一个包含许多FormControl的大表单,它每次都会触发验证,即使其他formco控件已更改。我认为只有当formcontrols的相应值发生更改时,才有一个解决方案可以验证。在这种小情况下,这是可以的,但如果我有一个包含许多formcontrols的大表单,则每次都会触发验证,即使其他formcontrols发生更改。我认为只有在适当的情况下,才有一个解决方案可以验证表单控件的值已更改