formGroup的Angular2设置值


91

因此,我有一个用于创建实体的复杂表格,我也想将其用于编辑,我正在使用新的角度表格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]" />

那行得通,但在数组的情况下会很痛苦


据我所知,当前不支持设置表单值,并且在下一次更新(RC.5)之后将受支持。请提供一个柱塞。
君特Zöchbauer

@GünterZöchbauer检查我当前的解决方案
Amgad Serry's

您看一下:github.com/angular/angular/blob/2.0.0-rc.5/modules/%40angular / ... 553行FormGroup.setValue()吗?
克莱门特

Answers:


298

要设置所有FormGroup值,请使用setValue

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

设置一些值,请使用patchValue

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

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


1
我在嵌套形式中使用patchValue,它覆盖了形式中的所有字段。(甚至我没有指定的人)知道我在做什么错吗?
恩里科

9

对于控件为FormGroup时的设置值,可以使用此示例

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


5

您可以使用form.get获取特定的控件对象并使用setValue

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


2

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

来自angular2 api docs NgModel选择器[ngModel]:not([formControlName]):not([formControl])angular.io/docs/ts/latest/api/forms/index / ...因此,即使现在可以使用稍后删除,我认为我将实施手动值注射器,因为这将是一个更稳定的解决方案
Amgad Serry's

@AmgadSerry,以确保它不会干扰那些组件(在选择器中)。在FormControlName明确地增加了它作为一个@Input()。查看我链接到的来源。如果这些否定选择器不存在,则在上面的示例中,将创建一个NgModel,而您不希望这样做。
Paul Samsotha '16

这有点令人困惑,但这就是它的实现方式。对于FormControlDirective[formControl])和FormControlNameformControlName),这都是这样的。如果在ngModel不使用的情况下使用,则假定您将使用声明性形式,并NgModel创建了一个。如果将ngModelNgModel
s

哦,我认为他们只是暂时仅在这两个指令上启用ngModel,因此以后会将其删除
Amgad Serry 2016年

检查我当前的解决方案
Amgad Serry's
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.