问题
I am trying to print get the value of Form Controls of Nested form on Console as well as in HTML.
userForm = new FormGroup({
name: new FormControl("Tom Alter"),
address: new FormGroup({
Country: new FormControl("India"),
State: new FormControl("Delhi")
})
});
In Both the cases, I am able to find the value using get statement.
console.log ("name : ", this.userForm.controls.name.value);
console.log ("Country using Get Way 1 : ", this.userForm.get(['address', 'Country']).value) ;
console.log ("Country using Get Way 2 : ", this.userForm.get(['address']).get(['Country']).value);
console.log ("Country using Get Way 3 : ", this.userForm.get(['address.Country']).value);
console.log ("Country without Get: ", this.userForm.group.address.controls.cCountry.value);
Out of these "Name", "Way1", "Way2" are working but, "Way 3" and "Without get" is not working as it is working for "name"
Similarly in HTML :
Name : {{userForm.controls.name.value}}
<br>
<br>
Country with get Way - 1 : {{userForm.get(['address']).get(['Country']).value}}
<br>
Country with get Way - 2 : {{userForm.get(['address','Country']).value}}
<br>
<br>
Country without get: {{userForm.address.controls.country.value}}
name and Way 1 is working fine, where as "Way-2" and "Without get" is not working.
Please point me to my mistake in the code.
Code is available on https://stackblitz.com/edit/angular-nestedformgroups
回答1:
way 3 should be without array
this.userForm.get('address.Country').value
Country without Get can be accessed through controlls
this.userForm.controls.address.controls.Country.value
in the template there is just a small mistake. you should have Country
instead of country
and also access through .controls
propery
{{userForm.controls.address.controls.country.value}}
回答2:
For Country without get : Replace "{{userForm.address.controls.country.value}}" with {{userForm.controls['address'].controls['Country'].value}}
回答3:
We've been facing at work a lot of issues with form and nested forms. After a lot of research around that topic to simplify our lives we came up with a library that we decided to open source. It's a super tiny wrapper that you can use for both reactive or template forms (would definitely recommend reactive ones though).
The library is called ngx-sub-form: https://github.com/cloudnc/ngx-sub-form The readme should contain everything you need to discover the library but I've also written an article here: https://dev.to/maxime1992/building-scalable-robust-and-type-safe-forms-with-angular-3nf9 to go more into details.
Now, I've transformed your stackblitz to use ngx-sub-form, here's how it'd look:
https://stackblitz.com/edit/user-nested-form-group?file=src/app/app.component.ts
Code:
app.component.ts
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
public userUpdate(user: User): void {
// every time the form changes
// this method will be called
console.log(user);
}
}
app.component.html
<app-user-form (userUpdate)="userUpdate($event)"></app-user-form>
user-form.component.ts
@Component({
selector: "app-user-form",
templateUrl: "./user-form.component.html",
styleUrls: ["./user-form.component.css"]
})
export class UserFormComponent extends NgxAutomaticRootFormComponent<User> {
@DataInput()
@Input("user")
public dataInput: Required<User>;
@Output("userUpdate")
public dataOutput: EventEmitter<User> = new EventEmitter();
protected getFormControls(): Controls<User> {
return {
name: new FormControl(null),
address: new FormControl(null),
};
}
}
user-form.component.html
<div [formGroup]="formGroup">
<input type="text" [formControlName]="formControlNames.name" placeholder="Name">
<app-address-control type="text" [formControlName]="formControlNames.address" placeholder="Address"></app-address-control>
</div>
<pre>{{ formGroupValues | json}}</pre>
<!-- So you can simply do: -->
<ul>
<li>Name: {{ formGroupValues.name }}</li>
<li>
Address
<ul>
<li>Country: {{ formGroupValues.address.country }}</li>
<li>State: {{ formGroupValues.address.state }}</li>
</ul>
</li>
</ul>
In the above, notice how easy it is to access the nested values
address-control.component.ts
@Component({
selector: "app-address-control",
templateUrl: "./address-control.component.html",
styleUrls: ["./address-control.component.css"],
providers: subformComponentProviders(AddressControlComponent)
})
export class AddressControlComponent extends NgxSubFormComponent<
Address
> {
protected getFormControls(): Controls<Address> {
return {
country: new FormControl(null),
state: new FormControl(null)
};
}
}
address-control.component.html
<div [formGroup]="formGroup">
<input type="text" [formControlName]="formControlNames.country" placeholder="Country">
<input type="text" [formControlName]="formControlNames.state" placeholder="State">
</div>
This is not the place to explain all the features of the library so I'll let you dig into the readme or article but by doing so you'll get extra type safety too when using AoT and many more things.
When looking at the demo also open the console to see that you can easily react whenever the form changes.
来源:https://stackoverflow.com/questions/59284468/angular-how-to-access-the-value-of-controls-in-nested-forms