【问题标题】:Display and update FormGroup inside FormArray在 FormArray 中显示和更新 FormGroup
【发布时间】:2020-09-29 22:21:37
【问题描述】:

我正在显示一个带有 *ngFor 的 FormArray。我想要做的是当我点击 ngFor 中的一个项目时,用该项目的“任务”属性填充。

此外,当我输入/更新输入内容时,原始表单会更新/修补。

HTML:

<form [formGroup]="myForm">

    <div [id]="i" 
        class="example-box"
        *ngFor="let item of myForm.get('items').controls; let i=index;"
        (click)="updateInput(item)">
        {{item.value.task}} to be
    </div>

  <br>
  <br>

  <input formControlName="xxx" />

  <br>
  <br>

    {{ myForm.value | json}}
</form>

组件.ts:

export class CdkDragDropSortingExample { 
  nominatedArray = [];
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.myForm = this.fb.group({
      title: ['title'],
      items: fb.array([
        fb.group({
          completed: fb.control(false),
          task: fb.control('Set Alarm'),
          position: fb.control(0)
        }),
        fb.group({
          completed: fb.control(false),
          task: fb.control('Brush teeth'),
          position: fb.control(1)
        }),
        fb.group({
          completed: fb.control(false),
          task: fb.control('Shower'),
          position: fb.control(2)
        }),
        fb.group({
          completed: fb.control(false),
          task: fb.control('Get ready'),
          position: fb.control(3)
        }),
        fb.group({
          completed: fb.control(false),
          task: fb.control('Have breakfast'),
          position: fb.control(4)
        })
      ])
    })
  }

  updateInput(item) {
    console.log(item);
  }    
}

Stackblitz:https://stackblitz.com/edit/angular-asevei-t5pm9u

【问题讨论】:

    标签: angular angular-reactive-forms angular-forms reactive-forms


    【解决方案1】:

    你可以声明一个变量

    control:FormControl
    

    并在您的输入表单控件中使用

    <input [formControl]="control" />
    

    一键点击

    (click)="control=item.get('task')
    

    但我认为您想“就地编辑”。为此,您需要两个变量,并且通常我会为 formArray 做一个吸气剂

    itemSelected:number=-1;
    dropping:boolean=false
    get items()
    {
        return (this.myForm.get('items') as FormArray)
    }
    

    我们的 .html 就像

    <form [formGroup]="myForm">
        <div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
    
            <div [id]="i" class="example-box" 
          [cdkDragDisabled]="itemSelected==i"
          (cdkDragDropped)="dropping=false"
                (cdkDragMoved)="dropping=true;itemSelected=-1"
                *ngFor="let item of items.controls; let i=index;" cdkDrag>
                <span *ngIf="itemSelected!=i" style="cursor:text" 
              (click)="!dropping && focus(i)" >
            {{item.value.task}} to be
        </span>
                <input #input *ngIf="itemSelected==i" [formControl]="item.get('task')" 
               (blur)="itemSelected=-1">
        </div>
    </div>
    </form>
    

    注意:要使用属性 cdkDragDisable,您需要更新您的引用,在 "@angular/cdk": "7.0.3" 中您没有此属性,因此您也需要更新到 Angular 9

    看看,如果“i=selectedIndex”,它会显示“输入”并且 cdkDrag 被禁用。当我们单击和拖动时,我们需要管理。为此,我使用变量 drop ,当你移动时为 true,在 drop 时为 false,此外,如果 drop 为 true,我们什么也不做,(click)="!dropping &amp;&amp; focus(i)"

    好吧,函数focus 将变量itemSelected 放到了行的值上并成为焦点。焦点需要在 setTimeout 中进行,以更改 Angular 以显示输入

      focus(i:number)
      {
        this.itemSelected=i
        setTimeout(()=>{
          this.input.nativeElement.focus()
        })
      }
    

    最后,drop 函数,需要考虑到函数 moveItemInArray 正在考虑使用数组,而不是 formArrays,所以

      drop(event: any) {
        const array=this.items.value //get the value of the formArray
        moveItemInArray(array, event.previousIndex, event.currentIndex); //move the value
        array.forEach((x:any,i:number)=>x.position=i)  //recalculate the position
        this.items.setValue(array)  //make a setValue
      }
    

    你可以在this stackblitz看到

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-14
      • 2018-09-03
      • 1970-01-01
      • 2021-04-03
      • 2018-10-03
      • 2021-08-14
      • 1970-01-01
      • 2017-11-09
      相关资源
      最近更新 更多