Angular2为formGroup设置值

问题描述 投票:0回答:7

因此,我有一个用于创建实体的复杂表单,我也想用它进行编辑,并且我正在使用新的角度表单 API。我的表单结构与从数据库检索的数据完全相同,因此我想将整个表单的值设置为检索到的数据,这里是我想要做的示例:

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 不适用于新表单 api,我也不介意在模板中使用一种数据绑定方式,如

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

这可行,但对于数组来说会很痛苦

angular angular2-forms
7个回答
395
投票

要设置 all FormGroup 值,请使用 setValue:

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

要设置仅某些值,请使用patchValue:

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

使用第二种技术,并非需要提供所有值,并且未设置值的字段不会受到影响。


20
投票

可以使用form.get获取具体的控件对象,使用setValue

this.form.get(<formControlName>).setValue(<newValue>);

12
投票

当你的控件是FormGroup时设置值可以使用这个例子

this.clientForm.controls['location'].setValue({
      latitude: position.coords.latitude,
      longitude: position.coords.longitude
    });

6
投票

是的,您可以使用 setValue 来设置值以进行编辑/更新。

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

您可以参考 https://musttoknow.com/use-angular-reactive-form-addinsert-update-data-using-setvalue-setpatch/ 了解如何使用 Reactive 表单通过 setValue 来添加/编辑功能。它节省了我的时间


4
投票

正如评论中指出的,提出此问题时不支持此功能。这个问题已在 Angular 2 rc5 中得到解决


3
投票

我已经实现了一个临时解决方案,直到 angular2 支持 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);
  }

用途:

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

注意:表单和数据必须具有相同的结构,我已经使用 lodash 进行深度克隆 jQuery,其他库也可以这样做


0
投票

“NgModel 不适用于新表单 api”。

这不是真的。您只需要正确使用它即可。如果您使用反应式形式,则应将 NgModel 与反应式指令配合使用。请参阅源代码中的示例

/* * @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" * } * } */

虽然它看起来像

TODO 注释,但这可能会被删除并替换为反应式 API。

// TODO(kara): Replace ngModel with reactive API @Input('ngModel') model: any;
    
© www.soinside.com 2019 - 2024. All rights reserved.