Проблема с валидацией formGroup внутри formArray - PullRequest
0 голосов
/ 01 января 2019

Я создаю форму с матовой таблицей угловых материалов.

При написании приложения я использую реактивную форму, и инициализация формы выглядит примерно так:

myForm = this.fb.group({
    settings: this.fb.array([])
});

моя форма представляет собой группу formGroup, которая содержит элемент управления formArray (параметры).

набор параметров formArray содержит formGroup для каждого параметра (каждая строка в таблице mat представляет собой группу formGroup и содержит количество элементов управления).

Моя проблема начинается, когда я пытаюсь добавить к ней валидацию.

Если у меня только что была formGroup с formControl внутри, и одним из них был Validators.required, например, форма была недействительной, пока я не добавил некоторые из них.значение, а затем оно изменилось бы на действительное состояние.

Однако при использовании formGroup внутри массива формы, даже после добавления некоторого значения в поле require, состояния формы остаются недействительными (я даже консоль регистрирую форму вчтобы увидеть, если внутреннее значение было изменено, и оно было).

Кроме того, когда я пытался поймать изменения, используя valueChange ().subscribe ... событие вызывалось только когда я выталкивал / удалял группы из formArray и никогда, когда существующий элемент управления внутри группы настроек был изменен.

Как я могу прослушивать события внутреннего изменения в группах внутри массива изатем использовать какие-либо пользовательские оценки для них?

Ответы [ 4 ]

0 голосов
/ 30 августа 2019

Я делал следующее:!

const array = (this.fg.get('addresses') as FormArray).controls;
array.push(this.fb.group({...}));

Хотя это должно было быть (нет controls)

const array = (this.fg.get('addresses') as FormArray);
array.push(this.fb.group({...}));
0 голосов
/ 02 января 2019

Используемая вами вложенная структура не должна влиять на правила проверки.Если FormControl недействителен, недопустимое состояние будет всплывать до корневого AbstractControl (в данном случае это ваша группа «myForm»).Angular справится со всем этим для вас.

Посмотрите на этот пример стекаблица с той же структурой формы, которую вы описали: https://stackblitz.com/edit/angular-xhppjs?file=src%2Fapp%2Fapp.component.html

Информация о бонусе:

Не пытайтесь перехватить значение ValueChanges для принудительного примененияправила проверки.Вам будет легче, если вы просто используете функции валидатора так, как задумал Angular.(https://angular.io/guide/form-validation#reactive-form-validation)

Вот список встроенных модулей Angular: https://angular.io/api/forms/Validators

Вот раздел о создании пользовательских функций валидатора, если встроенные модули не удовлетворяют вашим потребностям: https://angular.io/guide/form-validation#custom-validators

0 голосов
/ 02 января 2019

Спасибо за ваши ответы, мне удалось решить проблему, которая была в html-файле.

Когда я инициировал таблицу соответствия, я сделал следующее: [dataSource] = settings.value

делает это, представляя значения в таблице, но не обновляет элементы управления в formArray ...

Я решил это, изменив его на settings.controls и добавил [formGroupName] = index для каждого mat-ячейка

Спасибо за помощь.

0 голосов
/ 01 января 2019

Не видя больше вашего кода ... будет трудно догадаться, что может быть не так.

Но вот мой код для справки:

Код компонента

  get addresses(): FormArray {
    return <FormArray>this.customerForm.get('addresses');
  }

  ngOnInit() {
    this.customerForm = this.fb.group({
      firstName: ['', [Validators.required, Validators.minLength(3)]],
      lastName: ['', [Validators.required, Validators.maxLength(50)]],
      addresses: this.fb.array([this.buildAddress()])
    });
  }

  addAddress(): void {
    this.addresses.push(this.buildAddress());
  }

  buildAddress(): FormGroup {
    return this.fb.group({
      addressType: 'home',
      street1: ['', Validators.required],
      street2: '',
      city: '',
      state: '',
      zip: ''
    });
  }

Шаблон

    <div formArrayName="addresses"
         *ngFor="let address of addresses.controls; let i=index">

        <div class="form-group row mb-2">
          <label class="col-md-2 col-form-label"
                 attr.for="{{'street1Id' + i}}">Street Address 1</label>
          <div class="col-md-8">
            <input class="form-control"
                   id="{{'street1Id' + i}}"
                   type="text"
                   placeholder="Street address (required)"
                   formControlName="street1"
                   [ngClass]="{'is-invalid': (address.controls.street1.touched || 
                                              address.controls.street1.dirty) && 
                                              !address.controls.street1.valid }">
            <span class="invalid-feedback">
              <span *ngIf="address.controls.street1.errors?.required">
                Please enter your street address.
              </span>
            </span>
          </div>
        </div>
    </div>

Полный проект можно найти здесь: https://github.com/DeborahK/Angular-ReactiveForms/tree/master/Demo-Final

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...