Как реализовать проверку ввода реактивной формы Angular

Вот моя форма ниже: Текущие проверки ошибок в форме не работают.

<div formGroupName = "deliveryAddress">
<div class = "row mb-4">
    <div class = "col mb-4">
        <label class = "form-label">First Name</label>
        <input id = "firstName" class = "form-control fw-bold" type = "text" formControlName = "firstName"
            (change) = "saveToDataStore()">

        <div *ngIf = "firstName.invalid && (firstName.dirty || firstName.touched)" class = "alert alert-danger">
            <div *ngIf = "firstName.hasError('required')">
                First Name is required.
            </div>
        </div>
    </div>

    <div class = "col mb-4">
        <label class = "form-label">Last Name</label>
        <input id = "lastName" class = "form-control fw-bold" type = "text" formControlName = "lastName"
            (change) = "saveToDataStore()">

            <div *ngIf = "lastName.invalid && (lastName.dirty || lastName.touched)" class = "alert alert-danger">
                <div *ngIf = "lastName.hasError('required')">
                    Last Name is required.
                </div>
            </div>
    </div>

    <div class = "row mb-4">
        <div class = "col">
            <label class = "form-label">Phone Number</label>
            <input id = "phone" class = "form-control fw-bold" type = "phone" formControlName = "phone"
                (change) = "saveToDataStore()">
        </div>
    </div>
</div>

Вот объявление формы в компоненте:

private initCheckoutForm = () => {
this.checkoutForm = this.formBuilder.group({
  deliveryAddress: this.formBuilder.group({ 
    firstName: ['', Validators.required],
    lastName: ['', Validators.required],
    phone: ['', Validators.required],
    address1: ['', Validators.required],
    address2: [''],
    useAsBillingAddress: [''],
  }),
  applianceDelivery: this.formBuilder.group({ 
      deliveryDate: ['', Validators.required],
      specialInstructions: [''],
  }),
  paymentMethod: this.formBuilder.group({ 
      paymentType: ['', Validators.required],
      cardNumber: ['', Validators.required],
      expMonth: ['', Validators.required],
      expYear: ['', Validators.required],
      CVV: ['', Validators.required],
      defaultCreditCard: [''],
  })
});
    console.info('this.checkoutForm', this.checkoutForm.value);
  }

поделитесь кодом, используемым для получения свойств firstName, lastName и т. д., поделитесь рабочим примером на stackblitz, где возникает проблема

Naren Murali 21.08.2024 18:43

перепостить, нет? Вы проверяли комментарии к исходному вопросу?

browsermator 21.08.2024 19:26

Это совершенно не репост. Это новый пост того же приложения. Фактически, я решил предыдущий вопрос, который разместил.

koque 21.08.2024 20:28
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
3
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

если у вас нет таких геттеров, как

get firstName()
{
   return this.checkoutForm.get('deliveryAddress.firstName')
}
..same with the others: lastName, phone,...

Вы должны использовать это при проверке

   <div *ngIf = "checkoutForm.get('deliveryAddress.firstName').invalid && 
                  (checkoutForm.get('deliveryAddress.firstName').dirty || 
                   checkoutForm.get('deliveryAddress.firstName').touched)"> 

ПРИМЕЧАНИЕ. Если у вас есть только уникальный валидатор, вы можете не проверять hasError('required')

Что ж, сложно создать несколько установщиков или добавить в .html эти трудно читаемые «если», так почему бы не создать директиву?

@Directive({
  selector: '[formControlName],[formControl]',
  exportAs: 'ngControl',
  standalone: true,
})
export class ControlDirective {
  constructor(@Host() @Optional() private control: NgControl) {}
  get invalid() {
    return this.control?.invalid;
  }
  get touched() {
    return this.control?.touched;
  }
  get dirty() {
    return this.control?.dirty;
  }
  get value() {
    return this.control?.value;
  }
}

Затем мы можем использовать ссылочную переменную шаблона следующим образом #variable='ngControl' например

  form = new FormGroup({
    group: new FormGroup({
      control: new FormControl('', Validators.required),
    }),
  });

и использовать

  <form [formGroup] = "form">
    <div formGroupName = "group">
      <input #control = "ngControl" formControlName = "control" />
      @if (control.invalid && control.touched) { invalid }
    </div>
  </form>

стекблиц

Обновление. Другой способ показать ошибки — просто использовать .css.

.error {
  display: none;
}
.ng-invalid.ng-dirty + .error,
.ng-invalid.ng-touched + .error {
  display: block;
}

Итак, мы можем написать, например.

<input [formControl] = "controlName">
<div class = "error">Required</div>

Другие вопросы по теме

Angular: прокрутите страницу до раздела загрузки страницы при переходе к определенному фрагменту URL-адреса
Как обмениваться данными между (несколько экземплярами) двух несвязанных компонентов?
Как правильно расположить фиксированную панель навигации при прокрутке к разделам с одинаковым идентификатором в Angular?
Ошибка TS1383: только именованный экспорт может использовать «тип экспорта»
Angular Material 18: как изменить цвет фона?
Почему проблема NullInjectionError не решена путем добавления ProvideHttpClient() в файл app.config Angular 18
Правильно отформатируйте разделитель тысяч без регулярного выражения
CSS и JavaScript не применяются правильно после переноса содержимого HTML в компонент приложения Angular из-за проблем с инкапсуляцией просмотра и порядком загрузки скриптов
Как применить canActivateFn ко всем маршрутам в автономном приложении Angular?
Angular и Bootstrap — Маршруты