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

回答:


298

使用するすべてのFormGroup値を設定するには、setValue

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

一部ののみを設定するにpatchValueを使用します

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

この2番目の手法では、すべての値を指定する必要はなく、値が設定されていないフィールドは影響を受けません。


1
ネストされたフォームでpatchValueを使用していますが、フォーム内のすべてのフィールドが上書きされています。(私が指定していなくても)私が間違っていることについて何か考えはありますか?
エンリコ

9

コントロールがFormGroupの場合の設定値については、この例を使用できます

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

5

はい、setValueを使用して編集/更新の目的で値を設定できます。

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

http://musttoknow.com/use-angular-reactive-form-addinsert-update-data-using-setvalue-setpatch/を参照して、setValueを使用した追加/編集機能にリアクティブフォームを使用する方法を理解できます。それは私の時間を節約しました


5

form.getを使用して特定のコントロールオブジェクトを取得し、setValueを使用できます

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

3

コメントで指摘されているように、この質問が行われた時点では、この機能はサポートされていませんでした。この問題はAngular2rc5で解決されました


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});

注:フォームとデータは同じ構造である必要があり、jQueryのディープクローニングにlodashを使用しましたが、他のライブラリでも同様に実行できます


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;

angle2 api docs NgModelセレクター[ngModel]:not([formControlName]):not([formControl])angular.io/docs/ts/latest/api/forms/index/から取得…したがって、現在は機能していても、後で削除されます。より安定したソリューションになるため、手動値インジェクターを実装すると思います
Amgad Serry 2016

@AmgadSerryは、(セレクター内の)それらのコンポーネントに干渉しないことを確認するためのものです。FormControlName明示的として追加します@Input()。リンクしたソースを参照してください。これらの否定セレクターが存在しない場合は、上記の例を使用すると、不要なNgModelが作成されます。
Paul Samsotha 2016

少し紛らわしいですが、それが実装方法です。FormControlDirective[formControl])とFormControlNameformControlName)の両方で、これがどのように機能するかです。ngModelがこれらのいずれかなしで使用される場合、宣言型フォームを使用していると見なされNgModelが作成されます。場合はngModel使用されていると一緒の1反応性形ディレクティブ、その後、という反応型ディレクティブは、モデルではなく、処理しますNgModel
ポールSamsotha

ああ、私は彼らがそれらの2つのディレクティブでngModelを有効にするためのハックとして当分の間だけそれを作ったと思った、そして彼らは後でそれを削除するだろう
Amgad Serry 2016

私の現在の解決策を確認してください
Amgad Serry 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.