Angular2 menetapkan nilai untuk formGroup

91

Jadi saya memiliki formulir kompleks untuk membuat entitas dan saya ingin menggunakannya untuk mengedit juga saya menggunakan API bentuk sudut baru. Saya menyusun formulir persis seperti data yang saya ambil dari database jadi saya ingin mengatur nilai seluruh formulir ke data yang diambil di sini adalah contoh untuk apa yang ingin saya lakukan:

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 tidak bekerja dengan api bentuk baru juga saya tidak keberatan menggunakan data satu cara mengikat di template seperti pada

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

yang berfungsi tetapi akan merepotkan dalam kasus array

Amgad Serry
sumber
Sejauh yang saya tahu pengaturan nilai bentuk saat ini tidak didukung dan akan didukung setelah pembaruan berikutnya (RC.5). Harap berikan Plunker.
Günter Zöchbauer
@ GünterZöchbauer periksa solusi saya saat ini
Amgad Serry
Lihat: github.com/angular/angular/blob/2.0.0-rc.5/modules/%40angular/… line 553 FormGroup.setValue ()?
Clement

Jawaban:

298

Untuk mengatur semua nilai FormGroup gunakan, setValue :

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

Untuk menyetel hanya beberapa nilai, gunakan patchValue :

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

Dengan teknik kedua ini, tidak semua nilai perlu diberikan dan kolom yang nilainya tidak disetel tidak akan terpengaruh.

Stephen Paul
sumber
1
Saya menggunakan patchValue dalam formulir bersarang dan ini menimpa semua bidang di formulir. (bahkan yang tidak saya sebutkan) tahu apa yang saya lakukan salah?
Enrico
9

Untuk mengatur nilai ketika kontrol Anda adalah FormGroup dapat menggunakan contoh ini

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

Anda bisa menggunakan form.get untuk mendapatkan objek kontrol spesifik dan menggunakan setValue

this.form.get(<formControlName>).setValue(<newValue>);
Varadhan Work
sumber
3

Seperti yang ditunjukkan dalam komentar, fitur ini tidak didukung pada saat pertanyaan ini diajukan. Masalah ini telah diatasi di angular 2 rc5

Amgad Serry
sumber
2

Saya telah menerapkan solusi sementara sampai bentuk dukungan 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);
  }

pemakaian:

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

catatan: formulir dan data harus memiliki struktur yang sama dan saya telah menggunakan lodash untuk deepcloning jQuery dan libs lain juga dapat melakukannya

Amgad Serry
sumber
0

"NgModel tidak bekerja dengan api bentuk baru".

Itu tidak benar. Anda hanya perlu menggunakannya dengan benar. Jika Anda menggunakan formulir reaktif, NgModel harus digunakan sesuai dengan petunjuk reaktif. Lihat contoh di sumber .

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

Meskipun sepertinya dari komentar TODO , ini mungkin akan dihapus dan diganti dengan API reaktif.

// TODO(kara):  Replace ngModel with reactive API
@Input('ngModel') model: any;
Paul Samsotha
sumber
berasal dari angular2 api docs NgModel selector [ngModel]: not ([formControlName]): not ([formControl]) angular.io/docs/ts/latest/api/forms/index/… jadi bahkan jika berfungsi sekarang akan dihapus nanti saya pikir saya akan menerapkan injektor nilai manual karena akan menjadi solusi yang lebih stabil
Amgad Serry
@AmgadSerry yaitu untuk memastikan bahwa itu tidak mengganggu komponen tersebut (di selektor). Secara FormControlNameeksplisit menambahkannya sebagai file @Input(). Lihat sumber yang saya tautkan. Jika penyeleksi negasi itu tidak ada di sana, maka dengan contoh di atas, sebuah NgModel akan dibuat, yang tidak Anda inginkan.
Paul Samsotha
Ini sedikit membingungkan, tapi begitulah implementasinya. Untuk keduanya FormControlDirective( [formControl]) dan FormControlName( formControlName), begitulah cara kerjanya. Jika ngModeldigunakan tanpa salah satu dari itu, maka diasumsikan Anda akan menggunakan bentuk deklaratif , dan an NgModeldibuat. Jika ngModeldigunakan bersama salah satu reaktif arahan bentuk, maka yang reaktif bentuk direktif akan menangani model, bukanNgModel
Paul Samsotha
oh saya pikir mereka membuatnya sebagai peretasan untuk mengaktifkan ngModel pada dua arahan itu hanya untuk saat ini dan mereka akan menghapusnya nanti
Amgad Serry
periksa solusi saya saat ini
Amgad Serry