Angular 2: Lặp lại các điều khiển biểu mẫu phản ứng


97

Tôi muốn markAsDirtytất cả các điều khiển bên trong của a FormGroup.

Câu trả lời:


198

Tìm ra Object.keyscó thể xử lý điều này ..

    Object.keys(this.form.controls).forEach(key => {
      this.form.get(key).markAsDirty();
    });

Đối với Angular 8+, hãy sử dụng như sau (dựa trên câu trả lời của Michelangelo):

    Object.keys(this.form.controls).forEach(key => {
      this.form.controls[key].markAsDirty();
    });

2
Khi tôi sử dụng chức năng này trong onSubmit, tôi gặp lỗi Cannot invoke an expression whose type lacks a call signature. Type 'AbstractControl' has no compatible call signatures.Có ai biết tại sao không?
maidi

1
Object.keys (this.registerForm.controls) .forEach (key => {this.registerForm.controls [key] .markAsDirty ();});
Foad

Khi tôi thử Object.keys hoặc thậm chí là "for in", tôi không nhận được gì. Tuy nhiên, nếu tôi console.log (form.controls), tôi có thể XEM tất cả các điều khiển biểu mẫu khác nhau có trong đối tượng. Tôi bối rối.
Jake Shakesworth

Sử dụng Angular 5, markAsDirty () / markAsTouched () không đệ quy vào bất kỳ FormGroups con nào. Tôi đã chia đoạn mã trên thành một hàm đệ quy và gọi nó trên bất kỳ Nhóm con nào. Hoạt động tốt hơn với dự án Angular Material UI hiện tại trong trường hợp người dùng không bao giờ chạm vào phần tử bắt buộc, tôi gọi nó khi người dùng cố gắng gửi biểu mẫu để đánh dấu bất kỳ tại điểm đó.
Robert

3
Thnx để đọc bài của tôi và cập nhật câu trả lời của riêng bạn. Tài liệu chính thức cũng được lỗi thời vì vậy tôi phải tìm ra này bằng cách in mỗi dòng ...
Michelangelo

56

Đối với những gì nó đáng giá, có một cách khác để làm điều này mà không cần phải sử dụng phép thuật Object.keys (...) :

for (const field in this.form.controls) { // 'field' is a string

  const control = this.form.get(field); // 'control' is a FormControl  

}

làm thế nào để có được chỉ mục của vòng lặp?
SVK

1
Đối với những người sử dụng TSLint, mã hoạt động, nhưng TSLint phàn nàn với câu lệnh "for (... in ...) phải được lọc bằng câu lệnh if (forin)".
Yennefer

1
tslint đang chỉ ra, một trích dẫn từ tài liệu JavaScript của for ... in statement stackoverflow.com/questions/40770425/…
Egle Kreivyte

41

Câu trả lời được chấp nhận là đúng cho cấu trúc dạng phẳng, nhưng không hoàn toàn trả lời câu hỏi ban đầu. Một trang web có thể yêu cầu các Nhóm Form và FormArrays lồng nhau và chúng tôi phải tính đến điều này để tạo ra một giải pháp mạnh mẽ.

public markControlsDirty(group: FormGroup | FormArray): void {
    Object.keys(group.controls).forEach((key: string) => {
        const abstractControl = group.controls[key];

        if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
            this.markControlsDirty(abstractControl);
        } else {
            abstractControl.markAsDirty();
        }
    });
}

sẽ instanceofluôn hoạt động sau khi được chuyển đổi bởi Typecript?
đáng chú ý

@ the-đáng chú ý instanceofkhông phải là từ khóa cụ thể của TypeScript ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) Cũng không phải là classloại dữ liệu.
Keenan Diggs

8

Bằng cách sử dụng câu trả lời @Marcos, tôi đã tạo một hàm có thể được gọi là truyền một tham số formGroup và nó đánh dấu mọi điều khiển con của formGroup là bẩn, chỉ để làm cho nó có thể sử dụng được từ nhiều nơi hơn xung quanh mã đặt nó bên trong một dịch vụ chẳng hạn.

public touchAllFormFields(formGroup: FormGroup): void {
    Object.keys(formGroup.controls).forEach((key) => {
        formGroup.get(key).markAsDirty();
    });
}

hy vọng nó giúp ;)


Hoàn hảo! Đã thêm vào dịch vụ, cùng với các chức năng tương tự như clearValidators, unsouch, v.v. Có thể muốn thêm kiểm tra đệ quy cho các điều khiển lồng nhau, nhưng điều này hiện hoạt động. Cảm ơn!
mc01

6

Có vẻ như get chức năng đó không hoạt động nữa để truy xuất các giá trị cụ thể trong biểu mẫu của bạn trong Angular 8, vì vậy đây là cách tôi giải quyết nó dựa trên câu trả lời của @Liviu Ilea.

for (const field in this.myForm.controls) { // 'field' is a string
  console.log(this.myForm.controls[field].value);
}

Bạn có chắc không? Tài liệu API đã có sẵn phương thức get cho Điều khiển Tóm tắt ( angle.io/api/forms/AbstractControl#get ). Tôi vẫn chưa di cư. Bây giờ tôi sợ (⊙_ ◎)
Alan Grosz

@AlanGrosz Vâng, tôi cũng thấy điều đó khi viết lại nó nhưng ngay cả khi in tất cả các dòng trong bảng điều khiển, tôi không thể tìm thấy bất kỳ phương thức get nào trên đối tượng. Tôi nghĩ rằng tài liệu ở phía sau. Chúc may mắn khi di chuyển!
Michelangelo

Tôi không nghĩ rằng họ đã gỡ bỏ nó, lấy lại tác phẩm cho tôi trong Angular 8. Ngoài ra, nó vẫn còn trong tài liệu angle.io/api/forms/AbstractControl#get
Laszlo Sarvold

5

    Object.keys( this.registerForm.controls).forEach(key => {
       this.registerForm.controls[key].markAsDirty();
    });


4

Đây là những gì làm việc cho tôi

private markFormGroupTouched(formGroup: FormGroup) {
  Object.keys(formGroup.controls).forEach((key) => {
    const control = formGroup.controls[key];
    control.markAsDirty();
    if ((control instanceof FormGroup)) {
      this.markFormGroupTouched(control);
    }
  });
}

1

Tôi tạo chức năng này để làm cho nó * Tôi có một điều khiển với tên 'order' và chuyển chỉ mục cho anh ta.

{"conditionGroups": [
   {
     "order": null,
     "conditions": []
   }
  ]
}


updateFormData() {
    const control = <FormArray>this.form.controls['conditionGroups'];  
    control.value.map((x,index)=>{
    x.order = index; 
 })
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.