【问题标题】:How to force Angular 2 to re-check validator?如何强制 Angular 2 重新检查验证器?
【发布时间】:2017-02-10 12:15:14
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: forms angular validation


    【解决方案1】:

    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>

    【讨论】:

      【解决方案2】:

      我建议创建一个类似 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-09
        • 2018-09-28
        • 1970-01-01
        • 2016-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多