【问题标题】:Draggable formGroups in formArray (reactive forms)formArray 中的可拖动 formGroups(反应式表单)
【发布时间】:2019-10-02 14:30:59
【问题描述】:

在角度拖放模块中,他们提供了 moveItemInArray() 函数的文档,通过使用这个我们只能拖动数组中的内容。但是,我们如何在 formArray 中打乱(formGroups/formControls)?

即使我尝试了这个 moveItemInFormArray() 函数,正如这里提到的 https://github.com/angular/angular/issues/27171。但我不能让它工作。

groupDrag.component.html

    <form [formGroup]="exampleForm">
      <div formArrayName="formUnits" cdkDropList (cdkDropListDropped)="drop($event)" *ngFor="let unit of exampleForm.controls.formUnits.controls; let i=index" class="rowGroup">
        <div [formGroupName]="i" class="basic-container" cdkDrag>
          <div class="row row-container" >
            <button type="button" class="drag-handle" mat-icon-button cdkDragHandle>
              <mat-icon>unfold_more</mat-icon>
            </button>

            <!-- label input field -->
            <mat-form-field  class="col-lg-4"> 
              <input matInput placeholder="Please enter label without spaces" formControlName="label" required>  
            </mat-form-field>

            <!-- options input field -->
              <mat-form-field  class="col-lg-3"> 
                <input matInput placeholder="Enter Placeholdertext" formControlName="placeholder">
             </mat-form-field>

          </div>
        </div>
      </div>
    </form>

groupDrag.component.ts

drop(event: CdkDragDrop<FormGroup[]>) {
  console.log('drop event triggers')
  this.formArray = this.exampleForm.get('formUnits') as FormArray;
  const from = event.previousIndex;
  const to = event.currentIndex;
  this.moveItemInFormArray(this.formArray, from, to)
}

/**
* 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.
*/
moveItemInFormArray(formArray: FormArray, fromIndex: number, toIndex: number): void {
  const from = this.clamp(fromIndex, formArray.length - 1);
  const to = this.clamp(toIndex, formArray.length - 1);

  if (from === to) {
    return;
  }

  const delta = from > to ? 1 : -1;
  for (let i = from; i * delta < to * delta; i += delta) {
    const previous = formArray.at(i);
    const current = formArray.at(i + delta);
    formArray.setControl(i, current);
    formArray.setControl(i + delta, previous);
  }
}

/** Clamps a number between zero and a maximum. */
clamp(value: number, max: number): number {
  return Math.max(0, Math.min(max, value));
}

【问题讨论】:

    标签: angular drag-and-drop angular-cdk


    【解决方案1】:

    这是工作示例:

    groupDrag.component.ts

    import {moveItemInFormArray} from "./move-item-in-form-array";
    
    drop(event: CdkDragDrop<string[]>) {
        moveItemInFormArray(this.arrayControls, event.previousIndex, event.currentIndex);
    }
    

    move-item-in-form-array.ts

    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 from = fromIndex;
      const to = toIndex;
    
      const temp = formArray.at(from);
      for (let i = from; i * dir < to * dir; i = i + dir) {
        const current = formArray.at(i + dir);
        formArray.setControl(i, current);
      }
      formArray.setControl(to, temp);
    }
    
    

    【讨论】:

    • this.arrayControls 必须更新为您的数组,但非常感谢!
    【解决方案2】:

    这是我的工作解决方案

    在component.html中

        <form [formGroup]="exampleForm">
          <div cdkDropList (cdkDropListDropped)="drop($event)">
            <div formArrayName="formUnits" class="rowGroup"
              *ngFor="let unit of exampleForm.controls.formUnits.controls; let i=index"  
               cdkDrag>
              <div [formGroupName]="i" class="basic-container" cdkDrag>
                <div class="row row-container" >
                  <button type="button" class="drag-handle" mat-icon-button cdkDragHandle>
                    <mat-icon>unfold_more</mat-icon>
                  </button>
    
                  <!-- label input field -->
                  <mat-form-field  class="col-lg-4"> 
                    <input matInput placeholder="Please enter label without spaces" 
                    formControlName="label" required>  
                  </mat-form-field>
    
                  <!-- options input field -->
                  <mat-form-field  class="col-lg-3"> 
                    <input matInput placeholder="Enter Placeholdertext" formControlName="placeholder">
                 </mat-form-field>
    
              </div>
            </div>
          </div>
        </div>
       </form>
    

    在component.ts文件中

      drop(event: CdkDragDrop<string[]>) {
        this.formArray = this.exampleForm.get('formUnits') as FormArray;
        const from = event.previousIndex;
        const to = event.currentIndex;
        this.moveItemInFormArray(this.formArray, from, to);
      }
    
      /**
     * 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.
     */
      moveItemInFormArray(formArray: FormArray, fromIndex: number, toIndex: number): void {
        const from = this.clamp(fromIndex, formArray.length - 1);
        const to = this.clamp(toIndex, formArray.length - 1);
    
        if (from === to) {
          return;
        }
    
        const previous = formArray.at(from);
        const current = formArray.at(to);
        formArray.setControl(to, previous);
        formArray.setControl(from, current);
      }
    
      /** Clamps a number between zero and a maximum. */
      clamp(value: number, max: number): number {
        return Math.max(0, Math.min(max, value));
      }
    

    【讨论】:

    • 作为参考,这个链接很有用。在 AngularInDepth link.medium.com/ONGISEADi5 中使用 tim_deschryver 的新 Angular Material CDK 探索拖放
    • 在我的情况下,我从
      中删除了“cdkDrag”以解决索引问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多