如何强制 Angular 2 重新检查验证器?

问题描述 投票:0回答:3

我有一个用 Angular 2 反应式(数据驱动)模板编写的简单登录表单。它工作完美,但是当我刷新页面并且浏览器填充电子邮件+密码(自动完成)时,我的表单的有效属性似乎是错误的。

但是当我在表单无效时按任意键或单击页面中的任意位置时,角度会更新一些状态(我猜)并且我的表单变得有效。

如何触发该状态?我怎么能说“嘿,再检查一下我的表格。”?我无法触发自己的验证脚本,因为某些验证消息是警报。如果我这样做,当用户打开此页面时,他/她将看到这些警报。

我记得,我使用触发器('input')技巧来更新 ng-model。

forms angular validation
3个回答
16
投票

updateValueAndValidity()
就是您正在寻找的。该文档位于:AbstractControl。它可以强制重新计算控件的值和验证状态。

这是一个演示:

form.组件.ts

export class FormComponent implements OnInit {
  myform: FormGroup;

  // explicit validation of each field
  emailValid: AbstractControl;
  passwordValid: AbstractControl;

  constructor(private fb: FormBuilder) {
    this.myform = fb.group({
      'email': ['', Validators.required],
      'password': ['', Validators.required],
    });

    this.emailValid = this.myform.controls['email'];
    this.passwordValid = this.myform.controls['password'];
  }

    ngOnInit() {
        this.myform.get('email').valueChanges.subscribe(()=>forceValidAgain());
        this.myform.get('password').valueChanges.subscribe(()=>forceValidAgain());
    }

  forceValidAgain(){
    this.emailValid.updateValueAndValidity();
    this.passwordValid.updateValueAndValidity();
  }
}

form.component.html

<form [formGroup]="myform" (ngSubmit)="onSubmit(myform.value)">
  <div class="form-group">
    <label for="email">Email</label>
    <input type="email"
           class="form-control"
           id="email"
           name="email"
           [formControl]="myform.controls['email']"
           [ngClass]="{'is-invalid': !emailValid.valid && emailValid.touched }">
    <div
      class="invalid-feedback"
      *ngIf="emailValid.hasError('required')">
      This field is required
    </div>
  </div>

  <div class="form-group">
    <label for="password">Password</label>
    <input type="password"
           class="form-control"
           id="password"
           name="password"
           [formControl]="myform.controls['password']"
           [ngClass]="{'is-invalid': !passwordValid.valid && passwordValid.touched}">
    <div
      class="invalid-feedback"
      *ngIf="passwordValid.hasError('required')">
      This field is required
    </div>
  </div>
</form>


0
投票

我建议创建一个像 onValueChanged 这样的方法(Angular2 文档中提到),将其绑定到您的表单,并在组件初始化时执行它。因此,绑定到表单更改应该以这种方式完成:

this.form.valueChanges.subscribe((data) => { 
  this.onValueChanged(data)
});

执行例如下面的行,如下所示:

this.onValueChanged();

此执行应该可以通过组件初始化期间的验证来解决您的问题。

我认为文档(如下)中的方法实现非常清楚。

onValueChanged(data?: any) {
  if (!this.heroForm) { return; }

  const form = this.heroForm;
  for (const field in this.formErrors) {
    // clear previous error message (if any)
    this.formErrors[field] = '';
    const control = form.get(field);

    if (control && control.dirty && !control.valid) {
      const messages = this.validationMessages[field];
      for (const key in control.errors) {
        this.formErrors[field] += messages[key] + ' ';
      }
    }
  }
}

我指的是文档:https://angular.io/docs/ts/latest/cookbook/form-validation.html


0
投票

如果您使用 arrayForm 嵌套表单,则必须更新控件,然后更新父表单(数组项),然后更新主表单,它将起作用,例如:

control?.updateValueAndValidity();
parentForm.updateValueAndValidity();
this.mainForm.updateValueAndValidity();
© www.soinside.com 2019 - 2024. All rights reserved.