Как в Angular custom control вывести весь список ошибок контрола?

В Angular есть несколько способов получить список ошибок контрола в custom control. Рассмотрим два примера.

Первый способ - использование директивы ngModel. В Angular можно использовать директиву ngModel для создания custom control. Для того, чтобы получить список ошибок контрола, можно использовать событие ngModelChange и свойство ngModel:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'custom-control',
  template: `
    <input [ngModel]="value" (ngModelChange)="onChange($event)">
    <div *ngIf="errors" style="color: red;">
      <div *ngFor="let error of errors">
        {{ error }}
      </div>
    </div>
  `,
})
export class CustomControlComponent {
  @Input() value: string;
  @Input() set errors(value: any) {
    this.errorArray = [];
    for (const key in value) {
      if (value.hasOwnProperty(key)) {
        this.errorArray.push(key);
      }
    }
  }
  errorArray: string[];

  onChange(value: any) {
    // Обновляем значение контрола
    this.value = value;
    // Очищаем список ошибок
    this.errorArray = [];
  }
}

В этом примере мы создали custom control с использованием ngModel. При изменении значения контрола срабатывает метод onChange, в котором мы обновляем значение контрола и очищаем список ошибок. Список ошибок выводится с помощью директивы *ngFor, которая отображает каждую ошибку в отдельной <div>-обертке.

Второй способ - использование AbstractControl. В Angular можно использовать AbstractControl для создания custom control. Чтобы получить список ошибок контрола, необходимо использовать метод getError или свойство errors:

import { Component, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, AbstractControl } from '@angular/forms';

@Component({
  selector: 'custom-control',
  template: `
    <input [ngModel]="value" (ngModelChange)="onChange($event)">
    <div *ngIf="errors" style="color: red;">
      <div *ngFor="let error of errors">
        {{ error }}
      </div>
    </div>
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: CustomControlComponent,
      multi: true,
    },
  ],
})
export class CustomControlComponent implements ControlValueAccessor {
  @Input() value: string;
  propagateChange = (_: any) => { };

  constructor(public control: AbstractControl) {}

  get errors(): string[] {
    return Object.keys(this.control.errors || {});
  }

  onChange(value: any) {
    // Обновляем значение контрола
    this.value = value;
    // Очищаем список ошибок
    this.propagateChange(this.value);
  }

  writeValue(value: any): void {
    this.value = value;
  }

  registerOnChange(fn: any): void {
    this.propagateChange = fn;
  }

  registerOnTouched(): void { }
}

В этом примере мы также создали custom control с использованием AbstractControl. Метод getError возвращает список ошибок контрола, который мы используем для отображения ошибок через директиву *ngFor.

Оба примера демонстрируют различные подходы к созданию custom control в Angular и позволяют выводить список ошибок контрола. Выберите тот подход, который лучше всего подходит для вашего проекта.