角条件形式验证器

时间:2019-02-11 13:39:35

标签: angular forms validation

我知道网络上有很多关于同一主题的主题,但是我找不到适合自己的解决方案。

我有一个带有angular的formBuilder的表单,这是一个配置文件表单,我们可以在其中更改密码,因此我们有三个密码输入:旧密码输入,新密码输入和新密码确认。 / p>

这是表格:

this.editProfileForm = this.formBuilder.group({
  lastname: ['', Validators.required],
  firstname: ['', Validators.required],
  email: ['', [Validators.required, Validators.email]],
  phone: [this.phone.replace(/\s/g, ''), [Validators.pattern('[0-9]{10}')]],
  birthdate: ['', [Validators.required]],
  password: [''],
  new_password: [''],
  new_password_confirm: [''],
});
this.editProfileForm.setValidators([this.ageValidator, this.samePasswordValidator, this.requiredPasswordValidator]);

我想做的是仅在其中一个密码不为空的情况下才设置密码字段。如果用户开始输入密码字段之一,则必须输入三个。

这是我尝试的:

public requiredPasswordValidator(form: FormGroup): any {
  if (form.controls.password.value || form.controls.new_password.value || form.controls.new_password_confirm.value) {

    form.controls.password.setValidators([Validators.required]);
    form.controls.new_password.setValidators([Validators.required, Validators.minLength(6)]);
    form.controls.new_password_confirm.setValidators([Validators.required, Validators.minLength(6)]);
  }
}

似乎可行,但并非完美,只有当我开始在其上键入并擦除时才需要该字段,并且每个字段都需要这样做。例如,如果我在密码字段中键入,则不需要new和new_confirm,但是如果我在新的pw输入中键入随机字母并将其删除,则该字段是必需的。

我不知道我的解释是否很清楚,是否需要更多询问我。

谢谢。

修改

我尝试使用Ankur Jain解决方案,但仍然存在相同的问题:

这是功能:

public formControlValueChanged(): void {
    this.editProfileForm.get('password').valueChanges.subscribe(
      (mode: string) => {
        if (mode) {
          this.f.new_password.setValidators([Validators.required]);
          this.f.new_password_confirm.setValidators([Validators.required]);
        }
      });
  }

(我使用this.f是因为只需通过new_password和new_password确认它会抛出错误,this.f是一个返回editProfileForm.controls的函数)

我在ngOninit中称呼它

  this.formControlValueChanged();

我还尝试将this.editProfileForm.updateValueAndValidity();添加到函数中,但这没有任何改变。

3 个答案:

答案 0 :(得分:0)

在致电setValidators()之后尝试执行此操作:

form.controls.password.updateValueAndValidity();
form.controls.new_password.updateValueAndValidity();
form.controls.new_password_confirm.updateValueAndValidity();

根据文档updateValueAndValidity

  

重新计算控件的值和验证状态。

答案 1 :(得分:0)

您可以订阅表单的值更改事件。

formControlValueChanged() {
    this.editProfileForm.get('password').valueChanges.subscribe(
       (mode: string) => {
           if(mode){ 
               new_password.setValidators([Validators.required]);
               new_password_confirm.setValidators([Validators.required]);
            }
        });
}

在ngOnInit中:

ngOnInit() {
    this.formControlValueChanged();
}

答案 2 :(得分:0)

据我了解,如果其中一个字段中有某个值,那么您希望将所有值都设置为必填,如果没有,则不需要。因此,让我们检查一下,如果其中一个字段中有值,请在表单上设置一个错误...例如{ allRequired: true }。如果所有控件中都有值,请返回null

passwordsValidator(form: FormGroup): any {
  const ctrls = form.controls;
  if (ctrls.password.value && ctrls.new_password.value && ctrls.new_password_confirm.value) {
    return null;
  } else if (ctrls.password.value || ctrls.new_password.value || ctrls.new_password_confirm.value) {
    return { allRequired: true}
  }
  return null;
}

然后我们可以使用hasError在模板中显示错误:

<p *ngIf="editProfileForm.hasError('allRequired')">Password fields are required!</p>

这里是 StackBlitz