Unable to typing more than 1 character in input for FormArray within a FormArray for Reactive Forms

后端 未结 1 808
终归单人心
终归单人心 2021-02-06 17:30

I am thinking this could be a bug for Reactive Form. I would appreciate any help from more experienced Angular Experts.

Symptom: Unable to key in more than 1 character i

相关标签:
1条回答
  • 2021-02-06 17:42

    Cause

    You get this problem because you rely on formGroup.value which gets a new instance when any of the input value changes. Therefore your control tree will be recreated in DOM thus loosing the focus.

    The steps which create this problem are:

    • you change the input which reflect the value directly to the FormControl value
    • the formGroup.value changes
    • *ngFor iterates over the new value and creates new elements removing the old ones
    • the new element will have the previous element value but not the focus

    Why *ngFor creates new elements

    NgFor creates new elements because of trackBy which is by default the enumerated value. If the value changes, the element from DOM, which is tracked by the older value, is considered to be obsolete, thus being removed, and a new element is created for the new value. Even if the value appears to be the same, it is not, is just another instance of FormControl, as you are actually enumerating over the FormControls.

    In your case: *ngFor="let line of testForm.value.lines;... and *ngFor="let field of testForm.value.lines[0].fields;... are incorrect for this reason.

    Solution

    Here is an updated Plunker.

    Therefore the template should look like:

      <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 讨论(0)
提交回复
热议问题