Angular dynamici c formArray не может найти элементы управления - PullRequest
0 голосов
/ 13 марта 2020

У меня проблемы с созданием динамической c формы с помощью FormArray, я пытаюсь построить форму на основе массива, который содержит Object, описывающий строку базы данных. Цель состоит в том, чтобы показать пользователю каждую выбранную им строку с их текущими значениями, позволяя пользователю изменить их и отправить обратно.

Так что все должно быть модульным, потому что я не знаю ни количества строк, которые он выбрал, ни количества столбцов таблицы, и мне все еще нужно иметь возможность получать новые данные.

Мне удалось сделать что-то, что должно работать, но у меня все еще есть ошибка:

Error : Cannot find control with name: 'XXXXX'

Я чувствую, что это может быть история of lifeCycleHook, и html каким-то образом выполняется до того, как элементы управления настроены в машинописи.

Сначала я создал formArray с именем modifyForm и formBuilder

 modifyForm: FormArray;

 constructor private fb: FormBuilder){}

, а затем в моем ngOnInit Я создал функцию oop, которая заполняет modifyForm правильными элементами управления, а также заполняет внешний массив, который HTML будет использовать для создания пользовательского интерфейса.

Машинопись:

ngOnInit() {


    let internalObjects = {}

    for (let i = 0; i < this.selectedRows.length; i++) {
      const row = this.selectedRows[i];
      internalObjects = {}

      for (let y = 0; y < Object.keys(row).length; y++) {
        const key = Object.keys(row)[y];
        const value = Object.values(row)[y];

        if (key !== "#") {
          this.modifyForm.push(this.fb.control(i + key))
          internalObjects[key] = value;
        }
      }
      this.externalArray.push(internalObjects)
    }
  }
}

HTML:

<form [formGroup]="modifyForm">
        <div *ngFor="let object of externalArray; let item = index ">
                <div *ngFor="let value of object | keyvalue">
                    <mat-form-field>
                       <input matInput [formControlName]='item+value.key' [value]='value.value'>
                    </mat-form-field>
               </div>
         </div>
</form>

Что странно, так это то, что в конце функции ngOnInit я консоль Записываю элементы управления, которые, кажется, созданы, с правильными значениями, и все равно говорит, что не может их найти.

Циклы машинописи:

   for (const control of this.modifyForm.controls) {
      console.log(control.value)
    }

Результат:

1

Я знаю, что это много, чтобы переварить, я пытался дать как можно больше информации как я мог, и я надеюсь, что это не слишком сложно читать. Я искал несколько дней, и я все еще застрял здесь. Спасибо всем, кто мог помочь! :)

1 Ответ

1 голос
/ 13 марта 2020

Вы неправильно связываетесь с массивом форм. С помощью групп форм и массивов форм вы привязываетесь к ключу. В случае массивов форм это индекс.

this.modifyForm.push(this.fb.control(i + key))

Это добавление элемента управления формы со значением i + key к следующему доступному индексу в массиве форм.

In ваш HTML вы должны привязать к индексу вместо значения. Вам не нужно вручную устанавливать [value] - который исходит из привязки формы.

<input matInput [formControlName]='item' />

Где item - текущий индекс в массиве формы, как определено в *ngFor

Привязка к сложным объектам

Если вы хотите создать массив из нескольких элементов управления формой, вы должны настроить массив групп форм, и ваши директивы HTML будут отражать структуру вашей формы.

const formGroups: FormGroup[] = myArray.map(x => new FormGroup({
  prop1: new FormControl(x.prop1),
  prop2: new FormControl(x.prop2)
}));
this.form = new FormArray(formGroups);
<form [formGroup]="form">
  <div *ngFor="let item of myArray; let i = index"
      [formGroupName]="i"> <!-- <<< bind to the ith form array entry -->
    <input formControlName="prop1" />
    <input formControlName="prop2" />
  </div>
</form>

Привязка к неизвестным свойствам

Если вы не знаете, каковы ваши свойства объекта, вы можете создать свою форму из ключей объекта.

this.form = new FormArray(this.selectedRows.map(row => {
  const formGroup = new FormGroup({});
  Object.keys(row).forEach(key => { // <-- use Object.keys to iterate the object
    formGroup.addControl(key, new FormControl(row[key]));
  });
  return formGroup;
}));

И сгенерируйте HTML из ключей объекта

<form [formGroup]="form">
  <div *ngFor="let row of selectedRows;let i = index">                
    <div [formGroupName]="i">
      <!-- use the keyvalue pipe to iterate the key/value pairs of the object -->
      <span *ngFor="let keyvalue of row | keyvalue">
        <input [formControlName]="keyvalue.key" />
      </span>
    </div>
  </div>
</form>

DEMO: https://stackblitz.com/edit/angular-v1jd6x

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