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

时间:2017-02-10 12:15:14

标签: forms angular validation

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

但是当我按任意键或点击页面中的任何地方而表单无效时,角度会更新某些状态(我猜)并且我的表单生效。

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

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

2 个答案:

答案 0 :(得分:2)

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

这是一个演示:

form.component.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>

答案 1 :(得分: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