首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Angular4:表单无效,尽管字段中没有错误(使用自定义验证)

Angular4:表单无效,尽管字段中没有错误(使用自定义验证)
EN

Stack Overflow用户
提问于 2017-12-06 11:10:07
回答 2查看 5.1K关注 0票数 7

我试图使用自定义验证来验证表单。由于某些原因,我必须构建一个表单,可以更改电子邮件或设置新密码。由于这个原因,我不能使用Validators.required,因为密码字段只有在它们被触摸时才会成为必需的。

我的问题是,当输入验证得到解决时,表单仍然无效。

我做了一个例子来证明我的问题:

http://plnkr.co/edit/obF4gC5RHkXOOlCEsIuH?p=preview

代码语言:javascript
运行
复制
ngOnInit(): void {
    this.emailField = new FormControl('mail@mail.com', Validators.email);
    this.pw1 = new FormControl('', [this.passwordAreEqualValidator, Validators.minLength(2)]);
    this.pw2 = new FormControl('', this.passwordAreEqualValidator);
    this.pwOld = new FormControl('', this.notEmptyIfNewIsTouchedValidator);

    this.form = this.formBuilder.group({
      pw1: this.pw1,
      pw2: this.pw2,
      emailField: this.emailField,
      pwOld: this.pwOld
    });
  }

notEmptyIfNewIsTouchedValidator(control: FormControl) : ValidationErrors | null {
    if (control.dirty) {
      if (control.value === '') {
        return {
          oldPasswordEmpty: true
        }
      }

      const parent = control.parent,
            pw1 = parent.get('pw1'),
            pw2 = parent.get('pw2');

      // this will trigger nothing in template, this part is only
      // to mark form invalid if password was entered. passwordNew1
      // cannot be false by default as this is okay when you only
      // want to change your e-mail adress.
      if (pw1.value.length === 0) {
        pw1.setErrors({noPassword: true});
      } else {
        if (pw1.hasError('noPassword')) {
          let pw1Errors = pw1.errors;
          delete pw1Errors.noPassword;  
          pw1.setErrors(pw1Errors);
        }
      }

      console.log('pw1 errors: ', pw1.errors);
      console.log('pw2 errors: ', pw2.errors);
      console.log('old errors: ', control.errors);
    }

    return null;
  }

  passwordAreEqualValidator(control: FormControl): ValidationErrors | null {
    if (control.dirty) {
      const
        parent = control.parent,
        pwOld = parent.get('pwOld'),
        pw1 = parent.get('pw1'),
        pw2 = parent.get('pw2');

      if (pwOld.value === '') {
        pwOld.setErrors({oldPasswordEmpty: true})
      }

      if (pw1.value !== pw2.value) {
        return {
          notEqual: true
        };
      } else {
        let pw1Errors = pw1.errors;

        if (pw1.hasError('notEqual')) {
          delete pw1Errors.notEqual;
          pw1.setErrors(pw1Errors);
        }

        if (pw1.hasError('noPassword')) {
          delete pw1Errors.noPassword;
          pw1.setErrors(pw1Errors);
        }

        pw2.setErrors(null);

        console.log('pw1 errors: ', pw1.errors);
        console.log('pw2 errors: ', pw2.errors);
        console.log('old errors: ', pwOld.errors);
      }
    }

    return null;
  }

复制步骤:

  1. 输入密码(错误旧密码空显示)
  2. 重复密码(错误密码在两种密码匹配后才显示)
  3. 一旦您的重复密码匹配,为旧密码添加一个值(删除错误旧密码)
  4. 所有验证错误都被删除,但仍然表单无效。

为什么我的表格无效?

P.S:一旦我再次编辑我的pw1,我的表单就会生效,尽管错误的结果并没有改变。

EN

回答 2

Stack Overflow用户

发布于 2019-04-11 13:35:42

你在两个领域都设置了Validator .所发生的情况是,pw1在输入pw2时不会重新验证,因此在您返回并再次键入之前,pw1仍然是无效的。

在组件中,在ngOnInit的末尾,可以添加以下内容.

代码语言:javascript
运行
复制
    this.pw1.valueChanges().subscribe(() => this.pw2.updateValueAndValidity());
    this.pw2.valueChanges().subscribe(() => this.pw1.updateValueAndValidity());
票数 1
EN

Stack Overflow用户

发布于 2022-03-06 00:42:47

这个答案只与无效但没有错误的表单的问题有关,而不是对已识别的问题的回答。

我正在创建子表单;我的基本FormGroupFormGroupsFormArray作为组件。

代码语言:javascript
运行
复制
this.form = this.formBuilder.group({
  name: FormControl('', []),
  addresses: this.formBuilder.array([
    this.formBuilder.group({
      street: FormControl('', []),
      city: FormControl('', []),
      state: FormControl('', []),
      zip: FormControl('', []),
    }),
    this.formBuilder.group({
      street: FormControl('', []),
      city: FormControl('', []),
      state: FormControl('', []),
      zip: FormControl('', []),
    }),
  ]),
  phone: FormControl('',[]),
});

我在子表单中获得了错误,特别是在FormGroup中的FormArray中,但是顶层表单没有显示任何错误。我不得不在FormGroup里看FormArray

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47672909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档