Đặt giá trị thủ công cho điều khiển FormBuilder


173

Điều này đang khiến tôi phát điên, tôi đang ở dưới súng và không đủ khả năng để dành cả ngày cho việc này.

Tôi đang cố gắng tự đặt giá trị điều khiển ('dept') trong thành phần và nó chỉ không hoạt động - ngay cả các giá trị mới ghi vào bảng điều khiển đúng cách.

Đây là trường hợp FormBuilder:

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

Đây là trình xử lý sự kiện nhận bộ đã chọn:

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

Bây giờ khi biểu mẫu được gửi và tôi đăng xuất this.form, trường vẫn còn trống! Tôi đã thấy sử dụng ppl khác updateValue()nhưng đây là beta.1 và tôi không thấy đó là một phương pháp hợp lệ để gọi điều khiển.

Tôi cũng đã cố gắng gọi updateValueAndValidity()mà không thành công :(.

Tôi sẽ chỉ sử dụng ngControl="dept"trên phần tử biểu mẫu, giống như tôi đang làm với phần còn lại của biểu mẫu nhưng nó là một chỉ thị / thành phần tùy chỉnh.

<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>

Tôi đã gặp tình huống tương tự, kịch bản là giá trị được đặt trong http.get-subscribe và tải giá trị biểu mẫu, nhưng đặt dòng giá trị được thực thi trước, đăng ký thực sự được thực hiện sau đó là không đồng bộ. Vì vậy, thiết lập giá trị trong đăng ký đảm bảo thiết lập của nó. my2cents!
HydTechie

Câu trả lời:


324

Cập nhật: 19/03/2017

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

CŨ:

Bây giờ chúng tôi buộc phải thực hiện một loại diễn viên:

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

Tôi không đồng ý lắm. Hy vọng điều này sẽ được cải thiện trong các phiên bản trong tương lai.


6
Điều này hoạt động độc đáo, cảm ơn. Cũng cần xóa xác nhận: (<Control>this.form.controls['dept']).setErrors(null)
Người đàn ông được gọi là Haney

17
Hoặc chưa this.form.get('dept').setValue(selected.id):)
developer033

6
Chỉ cần một lưu ý. Bạn cũng có thể truy cập trực tiếp vào tài sản mà không cần một người lập chỉ mục. this.form.controls.dept.setValue(selected.id);
James Poulose

nhưng điều này sẽ không thực hiện xác nhận cho dữ liệu mới !! Làm cách nào để tự kích hoạt phát hiện thay đổi sau khi cập nhật?
ksh

1
Đó là năm 2019 đối với tôi công việc này:this.form.controls['dept'].setValue(selected.id);
John Lopez

98

Trong Angular 2 Final (RC5 +) có các API mới để cập nhật giá trị biểu mẫu. Các patchValue()phương pháp API hỗ trợ cập nhật hình thức một phần, nơi mà chúng ta chỉ cần xác định một số các lĩnh vực:

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

Ngoài ra còn có setValue()phương thức API cần một đối tượng với tất cả các trường biểu mẫu. Nếu thiếu một trường, chúng tôi sẽ gặp lỗi.


7
Chỉ cần thêm rằng kể từ bây giờ updateValue(từ câu trả lời được chấp nhận bởi Filoche) đang bị phản đối vìsetValue
superjos

2
Dưới đây là yêu cầu kéo chính thức trên Github và lý do để phản đối updateValue()và giới thiệu patchValuesetValue.
TheBrockEllis

nhưng điều này sẽ không thực hiện xác nhận cho dữ liệu mới !! Cách kích hoạt phát hiện thay đổi theo cách thủ công sau khi cập nhật
ksh

16

Aangular 2 cuối cùng đã cập nhật API. Họ đã thêm nhiều phương pháp cho việc này.

Để cập nhật điều khiển biểu mẫu từ bộ điều khiển, hãy làm điều này:

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

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

Không cần thiết lập lại lỗi

Người giới thiệu

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

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


sự khác biệt giữa hai - setValue()khi được gọi trên a formGroup/formBuilder, nó yêu cầu tất cả các giá trị dưới biểu mẫu được đặt. patchValue(), khi được gọi giống nhau, có thể được sử dụng để cập nhật các giá trị cụ thể.
Vibhor Dube

11

Bạn có thể sử dụng các phương pháp sau để cập nhật giá trị của điều khiển biểu mẫu phản ứng. Bất kỳ phương pháp nào sau đây sẽ phù hợp với nhu cầu của bạn.

Các phương thức sử dụng setValue ()

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

Các phương thức sử dụng patchValue ()

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

Phương thức cuối cùng sẽ lặp lại kỹ lưỡng tất cả các điều khiển trong biểu mẫu để không được ưu tiên khi cập nhật điều khiển đơn

Bạn có thể sử dụng bất kỳ phương thức nào bên trong trình xử lý sự kiện

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

Bạn có thể cập nhật nhiều điều khiển trong nhóm biểu mẫu nếu được yêu cầu sử dụng

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

9

Bạn có thể thử điều này:

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

Để biết thêm chi tiết, bạn có thể xem JS Doc tương ứng về tham số thứ hai của updateValuephương thức: https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model. ts # L269 .


Cảm ơn câu trả lời của bạn - tuy nhiên updateValue dường như không phải là một phương thức hợp lệ trong angular2 beta.1 - Phiên bản nào bạn có thể sử dụng phương thức đó?
Matthew Brown

1
Bản đánh máy đưa ra lỗi sau : error TS2339: Property 'updateValue' does not exist on type 'AbstractControl'. Trong thành phần đó, hình thức có loại ControlGroup. Có lẽ nếu tôi tạo chúng riêng lẻ với new Control()điều này sẽ hoạt động
Matthew Brown

5

Không ai trong số này làm việc cho tôi. Tôi phải làm:

  this.myForm.get('myVal').setValue(val);

Điều tương tự cũng xảy ra với tôi. Tại sao điều này là trường hợp?
Rehmanali Momin

3
  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);

Nếu bạn không muốn tự đặt từng trường.


2

@ Filoche's Angular 2 giải pháp cập nhật. Sử dụngFormControl

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

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

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

Ngoài ra, bạn có thể sử dụng giải pháp của @ AngularUniversity , sử dụngpatchValue


1

Tôi biết câu trả lời đã được đưa ra nhưng tôi muốn đưa ra một câu trả lời ngắn gọn về cách cập nhật giá trị của một biểu mẫu để những người mới khác có thể có được một ý tưởng rõ ràng.

cấu trúc biểu mẫu của bạn rất hoàn hảo để sử dụng nó làm ví dụ. vì vậy, trong suốt câu trả lời của tôi, tôi sẽ biểu thị nó dưới dạng.

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

vì vậy biểu mẫu của chúng tôi là một loại đối tượng Formgroup có ba FormControl .

Có hai cách để cập nhật giá trị mô hình:

  • Sử dụng phương thức setValue () để đặt giá trị mới cho một điều khiển riêng lẻ. Phương thức setValue () tuân thủ nghiêm ngặt cấu trúc của nhóm biểu mẫu và thay thế toàn bộ giá trị cho điều khiển.

  • Sử dụng phương thức patchValue () để thay thế bất kỳ thuộc tính nào được xác định trong đối tượng đã thay đổi trong mô hình biểu mẫu.

Các kiểm tra nghiêm ngặt của phương thức setValue () giúp bắt lỗi lồng nhau ở các dạng phức tạp, trong khi patchValue () không âm thầm với các lỗi đó.

Từ tài liệu chính thức của Angular tại đây

vì vậy, khi cập nhật giá trị cho một thể hiện của nhóm biểu mẫu có chứa nhiều điều khiển, nhưng bạn chỉ có thể muốn cập nhật các phần của mô hình. patchValue () là một trong những bạn đang tìm kiếm.

để xem ví dụ. Khi bạn sử dụng patchValue ()

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

nhưng khi bạn sử dụng setValue (), bạn cần cập nhật mô hình đầy đủ vì nó tuân thủ nghiêm ngặt cấu trúc của nhóm biểu mẫu. vì vậy, nếu chúng ta viết

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

Chúng ta phải vượt qua tất cả các thuộc tính của mô hình nhóm biểu mẫu. như thế này

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

nhưng tôi không sử dụng phong cách này thường xuyên. Tôi thích sử dụng cách tiếp cận sau đây để giúp giữ cho mã của tôi sạch hơn và dễ hiểu hơn.

Những gì tôi làm là, tôi khai báo tất cả các điều khiển như một biến riêng biệt và sử dụng setValue () để cập nhật điều khiển cụ thể đó.

Đối với mẫu trên, tôi sẽ làm một cái gì đó như thế này.

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

Khi bạn cần cập nhật điều khiển biểu mẫu, chỉ cần sử dụng thuộc tính đó để cập nhật nó. Trong ví dụ, người hỏi đã cố cập nhật điều khiển biểu mẫu khi người dùng chọn một mục từ danh sách thả xuống.

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.
}

Tôi đề nghị nên xem API Formgroup để biết cách tất cả các thuộc tính và phương thức của Formgroup.

Bổ sung : để biết về getter xem tại đây


1

Nếu bạn đang sử dụng điều khiển biểu mẫu thì cách đơn giản nhất để làm điều này:

this.FormName.get('ControlName').setValue(value);

-1

Mẹo: Nếu bạn đang sử dụng setValuenhưng không cung cấp mọi thuộc tính trên biểu mẫu, bạn sẽ gặp lỗi:

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

Vì vậy, bạn có thể bị cám dỗ để sử dụng patchValue, nhưng điều này có thể nguy hiểm nếu bạn đang cố cập nhật toàn bộ biểu mẫu. Tôi có một addresscái mà có thể không có stateOrProvincehoặc stateCdtùy thuộc vào đó là Hoa Kỳ hay trên toàn thế giới.

Thay vào đó, bạn có thể cập nhật như thế này - sẽ sử dụng null làm mặc định:

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.