Tetapkan Nilai secara Manual untuk Kontrol FormBuilder

176

Ini membuatku gila, aku di bawah pistol dan tidak mampu menghabiskan satu hari lagi untuk ini.

Saya mencoba untuk secara manual menetapkan nilai kontrol ('dept') di dalam komponen, dan itu tidak berfungsi - bahkan nilai baru log untuk menghibur dengan benar.

Berikut adalah Instance FormBuilder:

initForm() {
  this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required],
  });
}

Ini adalah pengendali acara yang menerima departemen yang dipilih:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].value = selected.id;
}

Sekarang ketika formulir dikirimkan dan saya logout this.formlapangan masih kosong! Saya telah melihat penggunaan ppl lain updateValue()tetapi ini adalah beta.1 dan saya tidak melihat itu sebagai metode yang valid untuk memanggil kontrol.

Saya juga mencoba menelepon updateValueAndValidity()tanpa hasil :(.

Saya hanya akan menggunakan ngControl="dept"pada elemen form, seperti yang saya lakukan dengan sisa form tetapi dengan direktif / komponen kustom.

<ng-select
  [data]="dept"
  [multiple]="false"
  [items]="depts"
  (selected)="deptSelected($event)" <!-- This is how the value gets to me -->
  [placeholder]="'No Dept Selected'"></ng-select>
Matthew Brown
sumber
Saya telah mengalami situasi yang sama, skenario adalah nilai ditetapkan di http.get-berlangganan dan memuat nilai formulir, tetapi pengaturan garis nilai dieksekusi terlebih dahulu, berlangganan benar-benar dieksekusi kemudian sebagai asinkron. jadi mengatur nilai dalam berlangganan pastikan set-nya. my2cents!
HydTechie

Jawaban:

326

Diperbarui: 19/03/2017

this.form.controls['dept'].setValue(selected.id);

TUA:

Untuk saat ini kami dipaksa melakukan pemeran:

(<Control>this.form.controls['dept']).updateValue(selected.id)

Saya tidak terlalu elegan. Semoga ini diperbaiki di versi mendatang.

Filoche
sumber
6
Ini bekerja dengan baik, terima kasih. Juga perlu menghapus validasi: (<Control>this.form.controls['dept']).setErrors(null)
Man Called Haney
17
Atau belum this.form.get('dept').setValue(selected.id):)
developer033
6
Hanya sebuah catatan. Anda juga dapat mengakses properti secara langsung tanpa pengindeks. this.form.controls.dept.setValue(selected.id);
James Poulose
tetapi ini tidak akan menjalankan validasi untuk data baru !! Bagaimana cara memicu deteksi perubahan secara manual setelah memperbarui?
ksh
1
Ini 2019 bagi saya ini bekerja:this.form.controls['dept'].setValue(selected.id);
John Lopez
98

Di Angular 2 Final (RC5 +) ada API baru untuk memperbarui nilai formulir. The patchValue()Metode API mendukung pembaruan bentuk parsial, di mana kita hanya perlu menentukan beberapa bidang:

this.form.patchValue({id: selected.id})

Ada juga setValue()metode API yang membutuhkan objek dengan semua bidang formulir. Jika ada bidang yang hilang, kami akan mendapatkan kesalahan.

Universitas Angular
sumber
7
Hanya untuk menambahkan bahwa mulai sekarang updateValue(dari jawaban yang diterima oleh Filoche) sedang ditinggalkan demisetValue
superjos
2
Ini adalah permintaan penarikan resmi pada Github dan alasan untuk mencela updateValue()dan memperkenalkan patchValuedan setValue.
TheBrockEllis
tetapi ini tidak akan menjalankan validasi untuk data baru !! Cara memicu deteksi perubahan secara manual setelah memperbarui
ksh
16

Final Aangular 2 telah memperbarui API. Mereka telah menambahkan banyak metode untuk ini.

Untuk memperbarui kontrol bentuk dari pengontrol, lakukan ini:

this.form.controls['dept'].setValue(selected.id);

this.form.controls['dept'].patchValue(selected.id);

Tidak perlu mengatur ulang kesalahan

Referensi

https://angular.io/docs/ts/latest/api/forms/index/FormControl-class.html

https://toddmotto.com/angular-2-form-controls-patch-value-set-value

tanveer ahmad dar
sumber
perbedaan antara keduanya - setValue()ketika dipanggil pada formGroup/formBuilder, ia membutuhkan semua nilai di bawah formulir yang akan ditetapkan. patchValue(), ketika dipanggil sama, dapat digunakan untuk memperbarui nilai tertentu.
Vibhor Dube
11

Anda bisa menggunakan metode berikut untuk memperbarui nilai kontrol formulir reaktif. Salah satu dari metode berikut ini sesuai dengan kebutuhan Anda.

Metode menggunakan setValue ()

this.form.get("dept").setValue(selected.id);
this.form.controls["dept"].setValue(selected.id);

Metode menggunakan patchValue ()

this.form.get("dept").patchValue(selected.id);
this.form.controls['dept'].patchValue(selected.id);
this.form.patchValue({"dept": selected.id});

Metode terakhir akan mengulang semua kontrol dalam formulir sehingga tidak disukai saat memperbarui kontrol tunggal

Anda dapat menggunakan salah satu metode di dalam pengendali event

deptSelected(selected: { id: string; text: string }) {
     // any of the above method can be added here
}

Anda dapat memperbarui beberapa kontrol dalam grup formulir jika perlu menggunakan

this.form.patchValue({"dept": selected.id, "description":"description value"});
vivekkurien
sumber
9

Anda bisa mencoba ini:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].updateValue(selected.id);
}

Untuk detail lebih lanjut, Anda bisa melihat pada JS Doc terkait mengenai parameter kedua updateValuemetode: https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model. ts # L269 .

Thierry Templier
sumber
Terima kasih atas balasan Anda - namun pemutakhiran tampaknya bukan metode yang valid di angular2 beta.1 - Versi manakah Anda dapat menggunakan metode itu?
Matthew Brown
1
Naskah memberikan error berikut: error TS2339: Property 'updateValue' does not exist on type 'AbstractControl'. Dalam komponen itu, formulir memiliki tipe ControlGroup. Mungkin jika saya membuatnya secara individual dengan new Control()ini akan berhasil
Matthew Brown
5

Tak satu pun dari ini bekerja untuk saya. Saya harus melakukan:

  this.myForm.get('myVal').setValue(val);
kenyal
sumber
Sama terjadi dengan saya. Mengapa demikian?
Rehmanali Momin
3
  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);

Jika Anda tidak ingin mengatur setiap bidang secara manual.

robottaxes
sumber
2

@ Diperbarui solusi Angular 2 Filoche's. MenggunakanFormControl

(<Control>this.form.controls['dept']).updateValue(selected.id)

import { FormControl } from '@angular/forms';

(<FormControl>this.form.controls['dept']).setValue(selected.id));

Atau Anda dapat menggunakan solusi @ AngularUniversity yang digunakanpatchValue

zurfyx
sumber
1

Saya tahu jawabannya sudah diberikan tetapi saya ingin memberikan jawaban singkat bagaimana cara memperbarui nilai formulir sehingga pendatang baru lainnya bisa mendapatkan ide yang jelas.

struktur formulir Anda sangat sempurna untuk digunakan sebagai contoh. jadi, sepanjang jawaban saya, saya akan menyatakannya sebagai formulir.

this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required]
  });

jadi formulir kami adalah tipe objek FormGroup yang memiliki tiga FormControl .

Ada dua cara untuk memperbarui nilai model:

  • Gunakan metode setValue () untuk menetapkan nilai baru untuk kontrol individu. Metode setValue () secara ketat mematuhi struktur grup formulir dan mengganti seluruh nilai untuk kontrol.

  • Gunakan metode patchValue () untuk mengganti properti yang didefinisikan dalam objek yang telah berubah dalam model formulir.

Pemeriksaan ketat metode setValue () membantu menangkap kesalahan bersarang dalam bentuk kompleks, sementara patchValue () gagal secara diam-diam pada kesalahan tersebut.

Dari dokumentasi resmi Angular di sini

jadi, Saat memperbarui nilai untuk contoh grup formulir yang berisi beberapa kontrol, tetapi Anda mungkin hanya ingin memperbarui bagian model. patchValue () adalah yang Anda cari.

mari kita lihat contohnya. Ketika Anda menggunakan patchValue ()

this.form.patchValue({
    dept: 1 
});
//here we are just updating only dept field and it will work.

tetapi ketika Anda menggunakan setValue () Anda perlu memperbarui model lengkap karena secara ketat mematuhi struktur grup formulir. jadi, jika kita menulis

this.form.setValue({
    dept: 1 
});
// it will throw error.

Kita harus melewati semua properti dari model grup formulir. seperti ini

this.form.setValue({
      name: 'Mr. Bean'
      dept: 1,
      description: 'spome description'
  });

tapi saya tidak sering menggunakan gaya ini. Saya lebih suka menggunakan pendekatan berikut yang membantu menjaga kode saya lebih bersih dan lebih mudah dipahami.

Apa yang saya lakukan adalah, saya mendeklarasikan semua kontrol sebagai variabel terpisah dan menggunakan setValue () untuk memperbarui kontrol tertentu.

untuk bentuk di atas, saya akan melakukan sesuatu seperti ini.

get companyIdentifier(): FormControl {
    return this.form.get('name') as FormControl;
}

get dept(): FormControl {
    return this.form.get('dept') as FormControl;
}

get description(): FormControl {
    return this.form.get('description') as FormControl;
}

ketika Anda perlu memperbarui kontrol formulir gunakan saja properti itu untuk memperbaruinya. Dalam contoh, penanya mencoba memperbarui kontrol formulir dept ketika pengguna memilih item dari daftar turun bawah.

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // instead of using this.form.controls['dept'].setValue(selected.id), I prefer the following.

  this.dept.setValue(selected.id); // this.dept is the property that returns the 'dept' FormControl of the form.
}

Saya sarankan untuk melihat FormGroup API untuk mengetahui bagaimana semua properti dan metode FormGroup.

Tambahan : untuk mengetahui tentang pengambil lihat di sini

Sadid Khan
sumber
1

Jika Anda menggunakan kontrol formulir maka cara paling sederhana untuk melakukan ini:

this.FormName.get('ControlName').setValue(value);
Raihan Ridoy
sumber
-1

Kiat: Jika Anda menggunakan setValuetetapi tidak memberikan setiap properti di formulir, Anda akan mendapatkan kesalahan:

Must supply a value for form control with name: 'stateOrProvince'.

Jadi Anda mungkin tergoda untuk menggunakannya patchValue, tetapi ini bisa berbahaya jika Anda mencoba memperbarui seluruh formulir. Saya punya addressyang mungkin tidak punya stateOrProvinceataustateCd bergantung pada apakah AS atau seluruh dunia.

Sebagai gantinya, Anda dapat memperbarui seperti ini - yang akan menggunakan nulls sebagai default:

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );
Simon_Weaver
sumber