Angular : How to access the value of controls in nested forms

天涯浪子 提交于 2019-12-24 04:31:18

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!