Angular 7如何手动触发垫错误?

时间:2019-05-22 08:49:10

标签: angular angular-material2 angular-validation

我有一个要验证的控件:

  <mat-form-field class="example-full-width">
    <input matInput placeholder="Title " required [formControl]="titleFormControl">
    <mat-error *ngIf="titleFormControl.hasError('required')">
      Title is <strong>required</strong>
    </mat-error>
    <mat-error *ngIf="titleFormControl.hasError('duplicate')">
      Name already used
    </mat-error>
  </mat-form-field>

在组件中我有类似的东西

titleFormControl = new FormControl('', {
    validators: [
      Validators.required,
      Validators.minLength(4)
    ],
  });

  ngOnInit(): void {
      this.titleFormControl.valueChanges
  .pipe(distinctUntilChanged()).subscribe(this.isNameDuplicate.bind(this))
  }

 isNameDuplicate(): void {
    const ret = this.data.findIndex((item, index) =>
      index !== this.selSheetIndex && item.id >= 0 && this.titleFormControl.value === item.title) >= 0;
    if (ret) {
      this.titleFormControl.setErrors({ 'duplicate': true });
      this.titleFormControl.markAsDirty(); // doesn't help neither :-/
    }
  }

如果我更改了文本,则mat-error会在标题丢失时立即显示。当我更改内容时,isNameDuplicate()导致错误,而控件出现错误'duplicate'

我希望mat-error会立即显示,但不知何故。 mat-error(对于'duplicate')的评估仅在我更改焦点(例如,转到另一个领域。 (当'required'立即显示时)

是否可以手动触发评估,以便立即显示'duplicate'错误mat-error

注意:我知道我可以使用错误匹配器来做到这一点,但坦率地说,我不知道如何对给定列表进行检查。因此,我正在寻找这种方法的解决方案。

2 个答案:

答案 0 :(得分:1)

将验证器替换为formControl的异步验证器,而不是ngOnInit

titleFormControl = new FormControl('', [
      Validators.required,
      Validators.minLength(4),
      this.isNameDuplicate.bind(this)
    ]
  );
 isNameDuplicate: ValidatorFn = (control: FormControl): {[s: string]: boolean} {
    const ret = this.data.findIndex((item, index) =>
    index !== this.selSheetIndex && item.id >= 0 && control.value === item.title) >= 0;
    return ret ? {duplicate: true} : {};
  }

答案 1 :(得分:1)

尝试使用此(ValidatorFn):

titleFormControl = new FormControl('', {
validators: [
  Validators.required,
  Validators.minLength(4),
  this.isNameDuplicate.bind(this) // <----- Custom validator method call
],
});


 isNameDuplicate(control: AbstractControl): { [key: string]: boolean } | null {
 const ret = this.data.findIndex((item, index) => index !== this.selSheetIndex && item.id >= 0 && this.titleFormControl.value === item.title) >= 0;
 if (ret) {
  return { duplicate: true };
 }
}

以html

 <mat-error *ngIf="titleFormControl.hasError('duplicate')">
  Name already used
</mat-error>