Angular2 set value for formGroup

2019-03-11 14:59发布

So I have a complex form for creating an entity and I want to use it for editing as well I am using new angular forms API. I structured the form exactly as the data I retrieve from the database so I want to set the value of the whole form to the data retrieved here is an example to what i want to do:

this.form = builder.group({
      b : [ "", Validators.required ],
      c : [ "", Validators.required ],
      d : [ "" ],
      e : [ [] ],
      f : [ "" ]
    });
this.form.value({b:"data",c:"data",d:"data",e:["data1","data2"],f:data});

PS: NgModel doesn't work with new forms api also i don't mind using one way data binding in template as in

<input formControlName="d" value="[data.d]" />

that works but it would be a pain in case of the arrays

6条回答
The star\"
2楼-- · 2019-03-11 15:08

To set all FormGroup values use, setValue:

this.myFormGroup.setValue({
  formControlName1: myValue1, 
  formControlName2: myValue2
});

To set only some values, use patchValue:

this.myFormGroup.patchValue({
  formControlName1: myValue1, 
  // formControlName2: myValue2 (can be omitted)
});

With this second technique, not all values need to be supplied and fields whos values were not set will not be affected.

查看更多
成全新的幸福
3楼-- · 2019-03-11 15:14

"NgModel doesn't work with new forms api".

That's not true. You just need to use it correctly. If you are using the reactive forms, the NgModel should be used in concert with the reactive directive. See the example in the source.

/*
 * @Component({
 *      selector: "login-comp",
 *      directives: [REACTIVE_FORM_DIRECTIVES],
 *      template: `
 *        <form [formGroup]="myForm" (submit)='onLogIn()'>
 *          Login <input type='text' formControlName='login' [(ngModel)]="credentials.login">
 *          Password <input type='password' formControlName='password'
 *                          [(ngModel)]="credentials.password">
 *          <button type='submit'>Log in!</button>
 *        </form>
 *      `})
 * class LoginComp {
 *  credentials: {login:string, password:string};
 *  myForm = new FormGroup({
 *    login: new Control(this.credentials.login),
 *    password: new Control(this.credentials.password)
 *  });
 *
 *  onLogIn(): void {
 *    // this.credentials.login === "some login"
 *    // this.credentials.password === "some password"
 *  }
 * }
 */

Though it looks like from the TODO comments, this will likely be removed and replaced with a reactive API.

// TODO(kara):  Replace ngModel with reactive API
@Input('ngModel') model: any;
查看更多
Animai°情兽
4楼-- · 2019-03-11 15:22

I have implemented a temporary solution until angular2 support form updateValue

 initFormGroup(form: FormGroup, data: any) {
        for(var key in form.controls) {
          console.log(key);
          if(form.controls[key] instanceof FormControl) {
            if(data[key]){
              let control = <FormControl>form.controls[key];
              this.initFormControl(control,data[key]);
            }
          } else if(form.controls[key] instanceof FormGroup) {
            if(data[key]){
              this.initFormGroup(<FormGroup>form.controls[key],data[key]);
            }
          } else if(form.controls[key] instanceof FormArray) {
            var control = <FormArray>form.controls[key];
            if(data[key])
            this.initFormArray(control, data[key]);
          }
        }
      }
      initFormArray(array: FormArray, data: Array<any>){
    if(data.length>0){
      var clone = array.controls[0];
      array.removeAt(0);
      for(var idx in data) {
        array.push(_.cloneDeep(clone));
        if(clone instanceof FormGroup)
          this.initFormGroup(<FormGroup>array.controls[idx], data[idx]);
        else if(clone instanceof FormControl)
          this.initFormControl(<FormControl>array.controls[idx], data[idx]);
        else if(clone instanceof FormArray)
          this.initFormArray(<FormArray>array.controls[idx], data[idx]);
      }
    }
  }


initFormControl(control: FormControl, value:any){
    control.updateValue(value);
  }

usage:

this.initFormGroup(this.form, {b:"data",c:"data",d:"data",e:["data1","data2"],f:data});

note: form and data must have the same structure and i have used lodash for deepcloning jQuery and other libs can do as well

查看更多
混吃等死
5楼-- · 2019-03-11 15:27

Yes you can use setValue to set value for edit/update purpose.

this.personalform.setValue({
      name: items.name,
      address: {
        city: items.address.city,
        country: items.address.country
      }
    });

You can refer http://musttoknow.com/use-angular-reactive-form-addinsert-update-data-using-setvalue-setpatch/ to understand how to use Reactive forms for add/edit feature by using setValue. It saved my time

查看更多
孤傲高冷的网名
6楼-- · 2019-03-11 15:31

For set value when your control is FormGroup can use this example

this.clientForm.controls['location'].setValue({
      latitude: position.coords.latitude,
      longitude: position.coords.longitude
    });
查看更多
神经病院院长
7楼-- · 2019-03-11 15:31

As pointed out in comments, this feature wasn't supported at the time this question was asked. This issue has been resolved in angular 2 rc5

查看更多
登录 后发表回答