Trong Angular, làm thế nào để thêm Validator vào FormControl sau khi điều khiển được tạo?


84

Chúng tôi có một thành phần có một biểu mẫu được xây dựng động. Mã để thêm điều khiển với trình xác thực có thể trông giống như sau:

var c = new FormControl('', Validators.required);

Nhưng hãy nói rằng tôi muốn thêm Trình xác thực thứ hai sau này . Làm thế nào chúng ta có thể thực hiện điều này? Chúng tôi không thể tìm thấy bất kỳ tài liệu nào về điều này trực tuyến. Tôi đã tìm thấy mặc dù trong các điều khiển biểu mẫu có setValidators

this.form.controls["firstName"].setValidators 

nhưng không rõ cách thêm trình xác thực mới hoặc trình xác thực tùy chỉnh.

Câu trả lời:


109

Bạn chỉ cần chuyển cho FormControl một mảng trình xác nhận.

Dưới đây là một ví dụ cho thấy cách bạn có thể thêm trình xác thực vào FormControl hiện có:

this.form.controls["firstName"].setValidators([Validators.minLength(1), Validators.maxLength(30)]);

Lưu ý, điều này sẽ đặt lại mọi trình xác thực hiện có mà bạn đã thêm khi tạo FormControl.


5
ha ... đôi khi bạn nhìn một cái gì đó quá lâu thì tốt nhất bạn nên bước đi. CẢM ƠN BẠN!!
melegant

1
Có cách nào để xác nhận loại bỏ
Abhijith ss

7
bất kỳ cách nào để làm điều này mà không ghi đè những cái cũ? hoặc bất kỳ cách nào để nối những cái mới?
danday74

1
@ danday74, hãy xem câu trả lời của Eduard Void ở cuối câu hỏi này. Nên chấp nhận câu trả lời imo. Anh ấy giải thích cách làm những gì bạn cần biết, mà tôi cũng cần biết cách làm.
Chris

6
Tôi cũng phải gọi .updateValueAndValidity()kiểm soát biểu mẫu sau khi thiết lập trình xác thực mới.
Keeleon

82

Để thêm vào những gì @Delosdos đã đăng.

Đặt trình xác thực cho một điều khiển trong FormGroup: this.myForm.controls['controlName'].setValidators([Validators.required])

Xóa trình xác thực khỏi điều khiển trong FormGroup: this.myForm.controls['controlName'].clearValidators()

Cập nhật FormGroup khi bạn đã chạy một trong hai dòng trên. this.myForm.controls['controlName'].updateValueAndValidity()

Đây là một cách tuyệt vời để thiết lập xác thực biểu mẫu của bạn theo chương trình.


1
Đối với tôi, nó hoạt động mà không có dòng cuối cùng, tôi khá chắc chắn rằng các phiên bản Angular mới sẽ cập nhật tính hợp lệ của biểu mẫu ngay bây giờ. Nhưng cảm ơn bạn đã cho chúng tôi biết về updateValueAndValidityphương pháp này, có thể hữu ích vào một ngày nào đó!
Nino Filiu

@NinoFiliu updateValueAndValidityvẫn được sử dụng để thực hiện xác thực và không được xử lý khác trong các phiên bản Angular mới hơn. Điều gì xảy ra là setValidatorscập nhật trình xác thực, nhưng không chạy kiểm tra xác thực và sau đó bạn sử dụng updateValueAndValidityđể thực hiện xác thực. Bạn phải đặt trình xác thực tại một điểm mà tính năng phát hiện thay đổi sẽ xử lý nó cho bạn, nhưng bạn sẽ thấy việc sử dụng updateValueAndValiditytrên nhóm hoặc điều khiển tùy thuộc vào trình xác thực mà bạn vừa đặt quan trọng - github.com/angular/angular/issues/19622#issuecomment- 341547884 .
mtpultz

4
Tôi đang sử dụng Angular 6 và không thể làm cho nó hoạt động mà không có updateValueAndValidity. Cảm ơn @shammelburg!
Oli Crt

1
Trên Angular 7 và nó cũng sẽ không hoạt động với tôi nếu không có dòng cập nhật cuối cùng.
David Findlay

Đúng. Nó hoạt động mà không có updateValueAndValidity(), nhưng trong một số trường hợp, nó không. nếu bạn thêm updateValueAndValidity()sau setValidators()Nó sẽ ngay lập tức ảnh hưởng đến những thay đổi liên quan đến kiểm soát . Vì vậy, tốt hơn là thêm updateValueAndValidity () `.
Jamith NImantha

72

Nếu bạn đang sử dụng ReativeFormModule và có formGroup được định nghĩa như sau:

public exampleForm = new FormGroup({
        name: new FormControl('Test name', [Validators.required, Validators.minLength(3)]),
        email: new FormControl('test@example.com', [Validators.required, Validators.maxLength(50)]),
        age: new FormControl(45, [Validators.min(18), Validators.max(65)])
});

bạn có thể thêm một trình xác thực mới ( và giữ những trình xác thực ) vào FormControl bằng cách tiếp cận này:

this.exampleForm.get('age').setValidators([
        Validators.pattern('^[0-9]*$'),
        this.exampleForm.get('age').validator
]);
this.exampleForm.get('email').setValidators([
        Validators.email,
        this.exampleForm.get('email').validator
]);

FormControl.validator trả về trình xác thực soạn thư chứa tất cả trình xác thực đã xác định trước đó.


13
Imo đây nên là câu trả lời được chấp nhận. Nó trình bày cách thêm trình xác thực như OP đã yêu cầu, nhưng cũng chỉ cho bạn cách giữ lại các trình xác thực đã đặt trước đó; đó là điều đầu tiên tôi tìm kiếm trên Google cách làm sau khi tôi đọc câu trả lời được chấp nhận, bởi vì tôi không muốn ghi đè một số trình xác thực mà tôi đã có, nhưng vẫn cần thêm các trình xác thực bổ sung theo chương trình. Cảm ơn bạn vì câu trả lời này @Eduard Void
Chris

3
Tôi đồng ý với người tiền nhiệm của tôi. Câu hỏi đặt ra là làm thế nào để thêm trình xác thực mới vào biểu mẫu điều khiển, chứ không phải làm thế nào để thay thế nó.
Plusce

5
Tôi đã làm control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);để có được kiểm tra nghiêm ngặt rỗng xung quanh
William Lohan

3

Tôi nghĩ câu trả lời đã chọn là không đúng, vì câu hỏi ban đầu là "làm thế nào để thêm trình xác nhận mới sau khi tạo formControl".

Theo như tôi biết, điều đó là không thể. Điều duy nhất bạn có thể làm là tạo một mảng động của trình xác nhận.

Nhưng những gì chúng tôi bỏ lỡ là có một hàm addValidator () để không ghi đè các trình xác nhận đã được thêm vào formControl. Nếu ai đó có câu trả lời cho yêu cầu đó, rất vui được đăng ở đây.


1
Bạn nghĩ control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);sẽ hiệu quả.
William Lohan

2
Xem câu trả lời của @Eduard Void 's stackoverflow.com/a/53276815/6656422
William Lohan

3

Ngoài câu trả lời của Eduard Void, đây là addValidatorsphương pháp:

declare module '@angular/forms' {
  interface FormControl {
    addValidators(validators: ValidatorFn[]): void;
  }
}

FormControl.prototype.addValidators = function(this: FormControl, validators: ValidatorFn[]) {
  if (!validators || !validators.length) {
    return;
  }

  this.clearValidators();
  this.setValidators( this.validator ? [ this.validator, ...validators ] : validators );
};

Sử dụng nó, bạn có thể đặt trình xác thực động:

some_form_control.addValidators([ first_validator, second_validator ]);
some_form_control.addValidators([ third_validator ]);
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.