【问题标题】:How to manage dynamic validators in ReactiveForms with Angular 2+?如何使用 Angular 2+ 在 ReactiveForms 中管理动态验证器?
【发布时间】:2018-12-20 16:36:44
【问题描述】:

这是我使用 StackOverflow 多年后的第一个问题,我会尽力做到最好。

我必须开发一个带有动态验证的动态表单,例如在法国(我工作的地方),我们有不同的地址样式:带有道路类型/道路名称和替代格式的标准方式。

this.adress = this.fb.group({
  roadType: ['', Validators.required],
  roadName: ['', [ Validators.required,
                   Validators.minLength(5),
                   Validators.maxLength(20)] ],
  altRoad: ['', [ Validators.required,
                  Validators.maxLength(20)] ]
});

如您所见,在初始化时,需要 3 个输入。 我必须执行的规则是至少输入 1 个地址,因此我在 valueChanges 上放置了一些观察者,当我们输入输入时,其他地址格式输入必须失去其“必需”验证。

this.altRoadSubscription = this.adress.get('altRoad').valueChanges.subscribe(val => {
        if (val && val !== ''){
            this.form.controls['roadType'].clearValidators();
            this.form.controls['roadType'].updateValueAndValidity();
            this.form.controls['roadName'].clearValidators();
            this.form.controls['roadName'].updateValueAndValidity();
        } else {

            this.form.controls['roadType'].setValidators(Validators.required);
            this.form.controls['roadName'].setValidators(Validators.required);
        }
    }
});

this.roadTypeSubscription = this.adress.get('roadType').valueChanges.subscribe(val => {
        const roadName = this.adress.controls['roadName'].value;

        if ((!val || val === '') && (!roadName || roadName === '')){
            this.adress.controls['altRoad'].setValidators(Validators.required);
        } else {
            this.adress.controls['altRoad'].clearValidators();
            this.adress.controls['altRoad'].updateValueAndValidity();
        }
});

this.roadNameSubscription = this.form.get('nomVoie').valueChanges.subscribe(val => {
  if ((!val || val === '') && (!roadType || roadType === '')){
      this.form.controls['altRoad'].setValidators(Validators.required);
  } else {
      this.form.controls['altRoad'].clearValidators();
      this.form.controls['altRoad'].updateValueAndValidity();
  }
})

真正重要的是其他验证者! 当我在一个地址到另一个地址之间切换并且必须构建一个通用/标准方法而不将验证器存储在表单控件。 (一切都将由父组件管理)

如何使用简单的 setValidators() 方法删除/添加单个验证器到验证器列表而不刷新所有其他验证器?

与/或

获取当前验证器列表是否有技巧? (将它们临时存储并仅将setValidators() 与我们想​​要保留的验证器一起使用)

我看到this question 带出了一个anwser,但它似乎不起作用,因为用作字符串的“控件”类型而不是期望AbstractControlAbstractControl.validator() 原型)

【问题讨论】:

    标签: angular angular-reactive-forms angular-forms


    【解决方案1】:

    您可以保留它们并更新错误,而不是动态设置验证器。

    这只是意味着如果一个字段的值是真实的,那么其他字段就不会出现required 错误。

    类似于 this stackblitz

    this.a1.valueChanges.subscribe(value => {
       if(value) { this.a2.setErrors(this.updateRequiredError(this.a2.errors)); }
    });
    
    updateRequiredError(currentErrors: Object) {
      let ret = {... currentErrors};
      if (ret['required']) { delete ret['required']; }
      if (!Object.keys(ret).length) ret = null;
      return ret;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 2017-09-22
      • 2017-05-01
      • 2017-08-07
      相关资源
      最近更新 更多