2017-06-21 28 views
1

我在想这可能是Reactive Form的一个错误。我将不胜感激来自更有经验的Angular Experts的任何帮助。无法在FormArray中输入FormArray输入多于1个字符的反应形式

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

次数:当输入内的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> 

+0

https://github.com/angular/angular.js/issues/13327 –

回答

1

原因

你遇到这个问题,因为你靠formGroup.value它得到一个新的实例时,任何输入值发生变化。因此,您的控制树将在DOM中重新创建,从而失去焦点。

其中创建此问题的步骤如下:

  • 你改变这直接体现出价值的 FormControl值的输入
  • formGroup.value改变
  • *ngFor迭代新值,并创建新删除旧元素的元素
  • 新元素将具有上一个元素值但不包含焦点

为什么* ngFor创造了新的元素

NgFor创建因为trackBy这是默认的枚举值的新元素。如果该值发生更改,则由旧值跟踪的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> 
+0

嗨andreim,我对你的帮助表示感谢。谢谢。 – edmondtm

+1

请注意,此'testForm.controls ['lines']。controls [i] .controls ['fields']。controls'可以很容易地替换为:'testForm.get('lines。'+ i +'.fields' ).controls' :) – developer033

+0

@ developer033谢谢!你说得对,有'get()'方法。我改变了答案以反映这一点。所以第一个循环是'testForm.get('lines')。controls',第二个是'line.get('fields').''。现在更清楚了。我应该多加注意代码可能会变得多糟糕:) – andreim