Угловое перетаскивание с помощью формы Array

У меня есть 2 массива. Я реализую перетаскивание Angular и хочу использовать FormArray для сохранения массива, в который был вставлен элемент.

Проблема в том, что я не могу применить formcontrol к div, так как он выдает ошибку

Ошибка: нет доступа к значению для управления формой с именем: 'language'

Вот HTML

      <div>

        <div class="example-container">
          <h2>Selected Languages</h2>
          <div
          cdkDropList
          #todoList="cdkDropList"
          [cdkDropListData]="anotherarray"
          [cdkDropListConnectedTo]="[doneList]"
          class="example-list"
          (cdkDropListDropped)="drop($event)"
           formControlName="language">
          <div class="list-group-item list-group-item-action " *ngFor="let item of anotherarray" cdkDrag>
            {{item}}
          </div>
        </div>
      </div>

      <div class="example-container">
        <h2>Available Languages</h2>

        <div
        cdkDropList
        #doneList="cdkDropList"
        [cdkDropListData]="testingarray"
        [cdkDropListConnectedTo]="[todoList]"
        class="example-list"
        (cdkDropListDropped)="drop($event)">
        <div class="list-group-item list-group-item-action " *ngFor="let item of testingarray" cdkDrag>{{item}}</div>
      </div>
      </div>

      </div>

      <button type="submit" class="btn btn-primary my-2" translate>saveButtonLabel
        <fa-icon *ngIf="saveIcon" [icon]="saveIcon" [spin]="saveIcon.iconName === 'spinner'"></fa-icon>
      </button>
    </form>

1 ответ

В API перетаскивания Angular Material есть функция moveItemInArray, как показано здесь.

Это поддерживает только обычные массивы, но, согласно ответу pierNik здесь, на Stackru, вы можете реплицировать функциональность FormArray с помощью следующей функции:

import { FormArray } from '@angular/forms';

/**
 * Moves an item in a FormArray to another position.
 * @param formArray FormArray instance in which to move the item.
 * @param fromIndex Starting index of the item.
 * @param toIndex Index to which he item should be moved.
 */

export function moveItemInFormArray(
  formArray: FormArray,
  fromIndex: number,
  toIndex: number
): void {
  const dir = toIndex > fromIndex ? 1 : -1;

  const item = formArray.at(fromIndex);
  for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) {
    const current = formArray.at(i + dir);
    formArray.setControl(i, current);
  }
  formArray.setControl(toIndex, item);
}

Затем в вызывающем коде вы передаете formArray вместо обычного массива.

get formControls(): FormArray {
    return this.form.get('arrayName') as FormArray;
}

constructor() {
    this.form = this.formBuilder.group({
      arrayName: this.formBuilder.array([]),
    });
}

drop(event: CdkDragDrop<string[]>) {
    moveItemInFormArray(
      this.formControls,
      event.previousIndex,
      event.currentIndex
    );
  }

См. Рабочий Stackblitz здесь

В настоящее время мы не можем использовать formControl с Angular Drag and Drop, так как он работает с div, и мы не можем добавить к нему formContol. Поэтому нам нужно использовать событие cdkDropListDropped, чтобы обновлять нашу модель вручную каждый раз, когда элемент был отброшен.

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