typescript 异步自定义验证会导致控制台出错:“无法读取 Object.eval [as updateDirectives] 处的 null 属性‘required’”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45431489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:46:46  来源:igfitidea点击:

Async custom validation causes an error to the console: "Cannot read property 'required' of null at Object.eval [as updateDirectives]"

angularvalidationtypescript

提问by Alex Zakruzhetskyi

Currently, I'm working on an assignment of reactive-forms by Maximilian Schwarzmüller Angular 4 tutorial. In the assignment, I had to create a reactive form, and I did. Then I had to create a custom async validator, that checks the value of the control. It shouldn't be equal to 'Test'. This is my typescript code:

目前,我正在研究 Maximilian Schwarzmüller Angular 4 教程的反应式形式分配。在作业中,我必须创建一个反应式表单,我做到了。然后我必须创建一个自定义的异步验证器,它检查控件的值。它不应该等于“测试”。这是我的打字稿代码:

import {Component, OnInit} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';

import {Observable} from 'rxjs/Observable';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  statuses = ['Stable', 'Critical', 'Finished'];
  signupForm: FormGroup;

  ngOnInit() {
    this.signupForm = new FormGroup({
      'projectName': new FormControl(null, [Validators.required], this.forbiddenName),
      'email': new FormControl(null, [Validators.required, Validators.email]),
      'projectStatus': new FormControl('Stable')
    });
  }

  onSubmit() {
    console.log(this.signupForm.value);
    console.log(this.signupForm);
  }

  forbiddenName(control: FormControl): Promise<any> | Observable<any> {
    const promise = new Promise<any>((resolve, reject) => {
      setTimeout(() => {
        if (control.value === 'Test') {
          resolve({'projectNameIsForbidden': true});
        } else {
          resolve(null);
        }
      }, 2000);
    });
    return promise;
  }

}

And here is my html:

这是我的 html:

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
        <div class="form-group">
          <label for="project-name">Project name</label>
          <input type="text" id="project-name" class="form-control" formControlName="projectName">
          <div class="help-block" *ngIf="!signupForm.get('projectName').valid && signupForm.get('projectName').touched">
            <span *ngIf="signupForm.get('projectName').errors['required']">Can't be empty!<br></span>

            <span *ngIf="signupForm.get('projectName').errors['projectNameIsForbidden']">This name is forbidden!</span>
          </div>
        </div>
        <div class="form-group">
          <label for="email">Email</label>
          <input type="email" id="email" class="form-control" formControlName="email">
          <div class="help-block" *ngIf="!signupForm.get('email').valid && signupForm.get('email').touched">
            <span *ngIf="signupForm.get('email').errors['required']">Can't be blank!<br></span>
            <span *ngIf="signupForm.get('email').errors['email']">Has invalid format!</span>
          </div>
        </div>
        <div class="form-group">
          <label for="project-status">Project Status</label>
          <select id="project-status" class="form-control" formControlName="projectStatus">
            <option *ngFor="let status of statuses">{{ status }}</option>
          </select>
        </div>
        <button class="btn btn-success" type="submit">Submit</button>
      </form>
    </div>
  </div>
</div>

It seems to work fine, it gives me the appropriate error messages in my view, but in the console, I receive an error on every keydown in the projectNamecontrol. This is the error:

它似乎工作正常,它在我的视图中为我提供了适当的错误消息,但是在控制台中,我在projectName控件中的每个按键按下时都会收到一个错误。这是错误:

enter image description here

在此处输入图片说明

So, why the error appears? Thanks ahead.

那么,为什么会出现错误呢?先谢谢了。

回答by AJT82

The cause of error is here:

错误原因在这里:

<span *ngIf="signupForm.get('projectName').errors['required']">
   Can't be empty!
</span>

While you are typing errorsbecomes null, and if you move from field before the async validator has done evaluating, errorswill be null, therefore Angular cannot read it. This can be solved using safe navigation operator:

当您输入 becomeerrorsnull,如果您在异步验证器完成评估之前从字段中移动,errorswill null,因此 Angular 无法读取它。这可以使用安全导航操作符来解决:

<span *ngIf="signupForm.get('projectName').errors?.required">

But as I prefer to show messages is using hasError, so I would change both validations to this instead:

但是因为我更喜欢显示消息正在使用hasError,所以我会将两个验证更改为:

<span *ngIf="signupForm.hasError('projectNameIsForbidden', 'projectName')">
<span *ngIf="signupForm.hasError('required', 'projectName')">