【问题标题】:Angular 5: Reactive Forms - Form group validation retrigger when form control updatedAngular 5:反应式表单 - 表单控件更新时重新触发表单组验证
【发布时间】:2018-04-11 04:16:06
【问题描述】:

我正在使用Angular 5 Reactive forms,并设置了一个form groupconfirmEmail 和两个form controls 作为emailconfirmEmail。我在form group 中进一步添加了validatorform controls 附加了required 验证。

My use case is:我想根据各个表单控件的值触发custom validation,如果自定义验证器返回为invalid,则将表单控件标记为有错误。

My issue is that:一旦form controls 被标记为错误,自定义验证器(在表单组上)不会触发,直到我再次触摸两个表单控件并更改它们的值。 理想情况下,我只想更新其中一个字段(以匹配另一个字段)并能够再次触发自定义验证。

示例代码:

@Component({...})
export class FormComponent implements OnInit {
  user: FormGroup;
  constructor(private fb: FormBuilder) {}
  ngOnInit() {
    this.user = this.fb.group({
      data: this.fb.group({
        email: ['', Validators.required],
        confirmEmail: ['', Validators.required]
      }, , { validator: validateEmail })
    });
  }

  const validateEmail = (control: AbstractControl): {[key: string]: boolean} => {
    const email = control.get('email');
    const confirmEmail = control.get('confirmEmail');

    if (email.value === confirmEmail.value) {
          return null;
     } else {
       this.setFieldAsInvalid(email);
       this.setFieldAsInvalid(confirmEmail);
       return { nomatch: true };
     }
  };

  private setFieldAsInvalid(field: AbstractControl) {
      field.setErrors({
        'invalid': true
      });
   }
}

任何解决此问题的建议或我应该采取的任何其他方法。

【问题讨论】:

  • 能否也附上html代码

标签: angular custom-validators


【解决方案1】:

当控件(电子邮件和确认电子邮件)保持不同的值时,您正在将它们更改为无效,但是 ValidatorFun 中的return null 只会将当前表单控件的有效更改为真,并非所有电子邮件和确认电子邮件


解决方案 1: 您可以通过field.setErrors(null) 将电子邮件和confirmEmail 恢复为有效,当它们保持相同的值时。

if (email.value === confirmEmail.value) {
  // clear custom error for all related controls
  this.setFieldAsValid(email);
  this.setFieldAsValid(confirmEmail);
  return null;
} else {
  this.setFieldAsInvalid(email);
  this.setFieldAsInvalid(confirmEmail);
  return { nomatch: true };
}


private setFieldAsValid(field: AbstractControl) {
  field.setErrors(null);
}

见固定demo


解决方案 2: 如果您只关心错误nomatch,您可以在formgroup data 上跟踪,看看它是否有nomatch 的错误,如下所示(也包含在上面的演示模板部分):

this.user.get('data').hasError('nomatch')     

提一下这种方式会让其他formcontrol失效。

【讨论】:

  • 当我尝试这样做时,碰巧因为字段第一次无效,我不得不更改它们以触发验证功能;尽管与您一起演示,但似乎在这里工作。感谢您的建议。
【解决方案2】:

我使用反应式方法创建了一个示例表单,其中我同时使用了内置验证器和自定义验证器。

打字稿:

export class AppComponent  {

  forbiddenEmails = ['test@test.com'];

  loginForm = new FormGroup({
    'name': new FormControl(null, [Validators.required]),
    'email': new FormControl(null, [Validators.required, Validators.email, this.customEmailValidator.bind(this)])
  });

  onSubmit(){
    console.log(this.loginForm.get('email').value);
  }

  customEmailValidator(control: FormControl): {[params: string]: boolean}{
    console.log(this.forbiddenEmails.indexOf(control.value));
    if(this.forbiddenEmails.indexOf(control.value) === 0){
      return {'forbiddenEmail': true};
    }else{
       return null;
    }
  }
}

模板:

   <h3>Basic Form</h3>
    <form class="form-horizontal"  [formGroup]='loginForm' (ngSubmit)="onSubmit()">
        <div class="form-group">
            <label for="name" class="col-sm-3 control-label">Name:</label>
            <div class="col-sm-6">
                <input type="text" 
                id="name" 
                class="form-control"
                formControlName='name' />
            </div>
            <div class="col-sm-3"></div>
            <span *ngIf='loginForm.get("name").invalid && loginForm.get("name").touched'>Pleas enter a valid name !!!</span>
        </div>
        <div class="form-group">
            <label for="email" class="col-sm-3 control-label">Email:</label>
            <div class="col-sm-6">
                <input type="email"
                 id="email"
                 class="form-control"
                 formControlName="email"/>
            </div>
            <div class="col-sm-3"></div>
            <span *ngIf='loginForm.get("email").invalid && loginForm.get("email").touched'>Pleas enter a valid email !!!</span>
        </div>
        <hr>
        <button class="btn btn-primary" 
        type="submit"
        [disabled]='!loginForm.valid'
        >Submit</button>
    </form>

链接:https://stackblitz.com/edit/angular-nwahpa?file=app%2Fapp.component.html

【讨论】:

  • 抱歉,您的解决方案没有解决我的问题
猜你喜欢
  • 2019-09-08
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多