Angular - formGroupName value change does not upda

2019-02-18 06:10发布

问题:

As described in the title, formGroupName value change does not update the form. (after hitting the button the value displayed in the input remains the same)

Here is a plunker.

@Component({
  selector: 'my-app',
  template: `
   <form [formGroup]="myForm">
    <div [formGroupName]="fgn">
        <input [formControlName]="'name'">
    </div>
</form>

<button (click)="formChange()" >Change</button>

{{fgn}}
<br>
{{myForm.value | json}}
  `,
})
export class App {

    private myForm: FormGroup;
    private fgn: String;

    ngOnInit() {
        this.fgn = 'zero';

        this.myForm = this.formBuilder.group({
            zero: this.formBuilder.group({
                name: 'Zero'
            }),
            one: this.formBuilder.group({
                name: 'One'
            })
        });
    }

    formChange() {
        this.fgn = 'one';
    }

    constructor(private formBuilder: FormBuilder) {

    }
}

回答1:

Not sure why it didn't work with the formControlName approach.

This seems to work though:

<input [formControl]="myForm.controls[fgn].controls['name']">

UPDATE:

You could use this workaround for AOT:

<input [formControl]="myForm.get(fgn + '.name')" />

(This is considered a workaround since this invokes the get method way too often)



回答2:

You were doing wrong. Correct code will be :

<form [formGroup]="myForm">
    <div>
        <input [formControl]="myForm.controls['zero'].controls['name']">
        {{myForm.controls['zero'].controls['name'].value}}
    </div>
</form>

<button (click)="formChange()" >Change</button>

{{fgn}}
<br>
{{myForm.value | json}}

Explanation

formControlName expects name of form control but you were using in a wrong way => [formControlName]. When you are passing a form control object rather than name of form control then you use [formControl]. Hope this will help



回答3:

I would recommend like instead of using,

<input [formControl]="myForm.controls[fgn].controls['name']">

use,

<form [formGroup]="myForm">
 <div [formGroup]="myForm.controls[fgn]">
  <input [formControlName]="'name'">
 </div>
</form>

The reason is, if you have n number of input fields, for example, more than 25 fields in a form, it is not a good practice to apply [formControl]="myForm.controls[fgn].controls['name']" kind of declaration in each field as this will take more time and looks like a nightmare if you want to modify any simple changes.

Instead, if you use [formGroup]="myForm.controls[fgn]", it will take care of the inner [formControlName] by itself. And this works well as I'm using it in my project.

Thanks to @Amit for initiating this idea in me.

Hope this helps. Happy optimized coding :)