无法在FormArray for Reactive Forms中为FormArray输入多于1个字符

时间:2017-06-21 13:08:47

标签: angular angular-reactive-forms

我认为这可能是Reactive Form的错误。我将非常感谢更有经验的Angular专家的帮助。

症状:在给定时间无法在输入中键入多个字符。

出现:当输入是FormArray中的FormArray

我已添加了一个Plunker链接,如下所示: https://embed.plnkr.co/zl2BQe/

//app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
 })
export class AppModule { }

//app.component.ts
import { Component, OnInit} from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  testForm: FormGroup; 

  ngOnInit(){
   this.testForm = new FormGroup({
   'lines': new FormArray([
    new FormGroup({
      'fields': new FormArray([
        new FormControl('')
      ])
     })
    ])
   })
  }

onAddLine(){
if(this.testForm.value.lines.length<10){
  (<FormArray>this.testForm.get('lines')).push(
    new FormGroup({
      'fields': new FormArray([
        new FormControl()
      ])
     })
   )
 }
}

onAddField(){
  // Not developed       
 }
}

//app.component.html
<div class="panel panel-default">
  <div class="panel-heading">
    Angular Reactive FormArray Error 
    <!--<button class="btn btn-primary" (click)="onAddField()">Add 
    Field</button>-->
    <button class="btn btn-primary" (click)="onAddLine()">Add 
    Line</button>
  </div>
<div class="panel-body">
  <form [formGroup]="testForm">
    <div class="form-inline" *ngFor="let line of testForm.value.lines; let i = index" formArrayName="lines">
      <div class="form-group">
        <span [formGroupName]="i">
          <span *ngFor="let field of testForm.value.lines[0].fields; let j = index" formArrayName="fields">
              <input type="text" class="form-control" [formControlName]="j">
              Please Type on Input Field
          </span>
        </span>
      </div>
    </div>
  </form>
</div>

1 个答案:

答案 0 :(得分:2)

<强>原因

您遇到此问题是因为您依赖于formGroup.value,当任何输入值发生更改时,它会获取新实例。因此,您的控制树将在DOM中重新创建,从而失去焦点。

产生此问题的步骤是:

  • 您将直接反映该值的输入更改为 FormControl
  • formGroup.value更改
  • *ngFor遍历新值并创建删除旧值的新元素
  • 新元素将具有前一个元素值,但不具有焦点

为什么* ngFor会创建新元素

NgFortrackBy而创建新元素,默认情况下为枚举值。如果值发生更改,则DOM中的元素(由旧值跟踪)将被视为已过时,因此将被删除,并为新值创建新元素。即使值看起来相同,但它不是FormControl的另一个实例,因为您实际上是在FormControl上进行枚举。

在你的情况下: *ngFor="let line of testForm.value.lines;...*ngFor="let field of testForm.value.lines[0].fields;... 因为这个原因是不正确的。

<强>解决方案

Here is an updated Plunker

因此模板应如下所示:

  <div class="panel panel-default">
    <div class="panel-heading">
      Angular Reactive FormArray Error 
      <!--<button class="btn btn-primary" (click)="onAddField()">Add Field</button>-->
      <button class="btn btn-primary" (click)="onAddLine()">Add Line</button>
    </div>
    <div class="panel-body">
      <form [formGroup]="testForm">
        <div class="form-inline" *ngFor="let line of testForm.get('lines').controls; let i = index" formArrayName="lines">
          <div class="form-group">
            <span [formGroupName]="i">
              <span *ngFor="let field of line.get('fields').controls; let j = index" formArrayName="fields">
                  <input type="text" class="form-control" [formControlName]="j">
                  Please Type on Input Field
              </span>
            </span>
          </div>
        </div>
      </form>
    </div>
  </div>