Angular 7 Как вручную вызвать mat-error? - PullRequest
1 голос
/ 22 мая 2019

У меня есть элемент управления, который я хочу проверить:

  <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 ]

2 голосов
/ 22 мая 2019

попробуйте с этим (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>
1 голос
/ 22 мая 2019

Замените ваш валидатор в асинхронном валидаторе 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} : {};
  }
...