Angular formControl как обрабатывать свойство массива - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть следующая Angular форма:

<form [formGroup]="futureForm" (ngSubmit)="onSaveFuture(futureForm.value)">
    // ...

    <div class="row" *ngFor="let value of atr.values" >
        <div class="col-md-6">
          <input type="text" class="form-control form-control-sm" value="{{value.prop1}}"
                 formControlName="values.prop1">
        </div>
        <div class="col-md-3">
          <input type="text" class="form-control form-control-sm" value="{{value.prop2}}"
                 formControlName="values.prop2">
        </div>
        <div class="col-md-3">
          <input type="text" class="form-control form-control-sm" value="{{value.prop3}}"
                 formControlName="values.prop3">
        </div>
    </div>

    // ...
</form>

Обратите внимание, что имя formGroup futureForm, и при отправке мы вызываем onSaveFuture.

Моя проблема в том, что atr.values, который проходит через *ngFor, является массивом. Я хочу, чтобы futureForm.value (параметр, который передается в функцию saveFuture), содержал массив с объектами значений в нем при отправке формы.

Возникает следующая проблема. Консоль говорит следующее:

Не удается найти элемент управления с именем: 'values.prop1'

Также при отправке я не получаю нужный массив. atr.values это даже не массив, а отдельный объект.

Как мне сделать так, чтобы мои разные входы соответствовали их соответствующей записи atr.values, чтобы значение отображалось и также передавалось как массив для функции onSaveFuture?

Мой компонент выглядит следующим образом:

export class SomeComponent implements OnInit {
  atr: IAtr;
  futureForm;

    // constructor..

    ngOnInit(): void {
        // ..
        this.futureForm = this.formBuilder.group({
          // ..
          values: this.atr.values,
        });
    }

    // onSaveFuture..
}

Есть ли что-то, чего мне не хватает, или мне нужно использовать что-то другое, кроме formControlName ?? Заранее спасибо.

1 Ответ

1 голос
/ 30 апреля 2020

если ваши данные являются массивом, вам нужен FormArray, который немного сложнее, чем обычные группы форм.

ngOnInit(): void {
    // ..
    this.futureForm = this.formBuilder.group({
      // ..
      // initialize with array of groups
      values: this.formBuilder.array(this.atr.values.map(v => this.getValueGroup(v))),
    });

}

get valuesForm() {
  return this.futureForm.get('values') as FormArray
}

private getValueGroup(v?) {
  return this.formBuilder.group({
     // value group properties
     prop1: [v ? v.prop1 : ''] // something like this, initialize to prop value or default, add validators or whatever
  })
}

addValue(v?) {
  // use this to add new values
  const vg = this.getValueGroup(v);
  this.valuesForm.push(vg);
}

removeValue(index: number) {
  // remove values
  this.valuesForm.removeAt(index);
}

тогда в шаблоне все будет выглядеть иначе:

<ng-container formGroupName="values"> <!-- need some wrapper to build the path to the array... still uses formGroupName even though array --> 
    <div class="row" *ngFor="let ctrl of valuesForm.controls; let i = index" [formGroupName]="i"> <!-- iterate the controls,  group names are the index -->
        <div class="col-md-6">
          <input type="text" class="form-control form-control-sm"
                 formControlName="prop1"> <!-- just the property name, don't explicitly assign value -->
        </div>
        <div class="col-md-3">
          <input type="text" class="form-control form-control-sm" 
                 formControlName="prop2">
        </div>
        <div class="col-md-3">
          <input type="text" class="form-control form-control-sm" 
                 formControlName="prop3">
        </div>
    </div>
<ng-container>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...