Cách tìm các điều khiển không hợp lệ ở dạng phản ứng góc 4


89

Tôi có một biểu mẫu phản ứng trong Angular như dưới đây:

this.AddCustomerForm = this.formBuilder.group({
    Firstname: ['', Validators.required],
    Lastname: ['', Validators.required],
    Email: ['', Validators.required, Validators.pattern(this.EMAIL_REGEX)],
    Picture: [''],
    Username: ['', Validators.required],
    Password: ['', Validators.required],
    Address: ['', Validators.required],
    Postcode: ['', Validators.required],
    City: ['', Validators.required],
    Country: ['', Validators.required]
});

createCustomer(currentCustomer: Customer) 
{
    if (!this.AddCustomerForm.valid)
    {
        //some app logic
    }
}

this.AddCustomerForm.valid trả về false, nhưng mọi thứ có vẻ ổn.

Tôi đã cố gắng tìm bằng cách kiểm tra thuộc tính trạng thái trong bộ sưu tập điều khiển. Nhưng tôi tự hỏi liệu có cách nào để tìm những cái không hợp lệ và hiển thị cho người dùng không?


Trong số bạn chỉ muốn hiển thị các trường có lỗi, bạn có thể sử dụng css để đánh dấu hoặc tô màu các trường không hợp lệ. Mỗi trường hợp lệ có một lớp "ng-invalid" nối trong danh sách các lớp học
LookForAngular

Câu trả lời:


168

Bạn có thể chỉ cần lặp lại mọi điều khiển và kiểm tra trạng thái:

public findInvalidControls() {
    const invalid = [];
    const controls = this.AddCustomerForm.controls;
    for (const name in controls) {
        if (controls[name].invalid) {
            invalid.push(name);
        }
    }
    return invalid;
}

1
cảm ơn vì điều này nhưng tôi đã thử điều này và thậm chí điều này không trả lại gì, biểu mẫu của tôi vẫn không hợp lệ, điều này thật kỳ lạ. Ý tôi là mã này trông đẹp nhưng không hiểu sao form.valid trả về false
sa_

cái gì findInvalidControls()trả lại cho bạn?
Max Koretskyi

1
nó không trả về gì, không hợp lệ là trống. Tôi đã kiểm tra từng cái một trong màn hình đồng hồ gỡ lỗi, tất cả các điều khiển đều hợp lệ nhưng this.AddCustomerForm.valid vẫn trả về false.
sa_ 21/07/17

Tôi nghĩ rằng tôi đã phát hiện ra. có một trường email và biểu thức chính quy nhưng bằng cách nào đó, trạng thái của điều khiển là ĐANG ĐANG XỬ LÝ và đó có thể là nguyên nhân
sa_

7
@ AngularInDepth.com - nếu một trong các điều khiển là một nhóm biểu mẫu, thì hàm của bạn sẽ trả về nhóm biểu mẫu không hợp lệ chứ không phải điều khiển biểu mẫu cụ thể không hợp lệ
john Smith

35

Tôi vừa đấu tranh với vấn đề này: Mọi trường biểu mẫu đều hợp lệ, nhưng bản thân biểu mẫu vẫn không hợp lệ.

Hóa ra rằng tôi đã đặt 'Validator.required' trên FormArray nơi các điều khiển được thêm / xóa động. Vì vậy, ngay cả khi FormArray trống, nó vẫn được yêu cầu và do đó biểu mẫu luôn không hợp lệ, ngay cả khi mọi điều khiển hiển thị đã được điền chính xác.

Tôi không tìm thấy phần không hợp lệ của biểu mẫu, vì hàm 'findInvalidControls' của tôi chỉ kiểm tra FormControl's chứ không phải FormGroup / FormArray. Vì vậy, tôi đã cập nhật nó một chút:

/* 
   Returns an array of invalid control/group names, or a zero-length array if 
   no invalid controls/groups where found 
*/
public findInvalidControlsRecursive(formToInvestigate:FormGroup|FormArray):string[] {
    var invalidControls:string[] = [];
    let recursiveFunc = (form:FormGroup|FormArray) => {
      Object.keys(form.controls).forEach(field => { 
        const control = form.get(field);
        if (control.invalid) invalidControls.push(field);
        if (control instanceof FormGroup) {
          recursiveFunc(control);
        } else if (control instanceof FormArray) {
          recursiveFunc(control);
        }        
      });
    }
    recursiveFunc(formToInvestigate);
    return invalidControls;
  }

3
Câu trả lời vô cùng hữu ích. Cảm ơn bạn rất nhiều
Mikki

1
Đồng ý, câu trả lời rất hữu ích.
nenea

20

Trong DevTools trong Chrome, chọn tab Bảng điều khiển.

Trong bảng điều khiển, gõ lệnh nhắc:

document.getElementsByClassName('ng-invalid')

Đầu ra phải tương tự như sau: nhập mô tả hình ảnh ở đây

Trong trường hợp này, văn bản được gạch chân là để kiểm soát biểu mẫu listen-address. Và văn bản bao quanh: .ng-invalidcho biết rằng điều khiển không hợp lệ.

Lưu ý: Đã thử nghiệm trong chrome


2
đối với tôi đây dường như là cách trực tiếp nhất để trả lời câu hỏi.
ckapilla

2
Bạn đã cứu tôi khỏi phát điên, giá như tôi có thể mua đồ uống cho bạn
Adam Winnipass

3

Cả biểu mẫu và tất cả các điều khiển của bạn đều mở rộng lớp góc cạnh AbstractControl. Mỗi triển khai có một trình truy cập vào các lỗi xác thực.

let errors = this.AddCustomerForm.errors
// errors is an instance of ValidatorErrors

Tài liệu api chứa tất cả các tham chiếu https://angular.io/api/forms/AbstractControl

Biên tập

Tôi nghĩ rằng trình truy cập lỗi hoạt động theo cách này tuy nhiên liên kết này tới github cho thấy rằng có một số người khác cũng nghĩ như tôi https://github.com/angular/angular/issues/11530

Trong mọi trường hợp, bằng cách sử dụng công cụ truy cập điều khiển, bạn có thể lặp lại tất cả các formControls trong biểu mẫu của mình.

Object.keys(this.AddCustomerForm.controls)
    .forEach( control => {
        //check each control here
        // if the child is a formGroup or a formArray
        // you may cast it and check it's subcontrols too
     })

1
điều này trả về null ngay cả khi có các điều khiển trống
sa_

1
Nó sẽ trả về null khi không có lỗi. Bạn có thể đăng mẫu của bạn?
LookForAngular

Vâng, điều này sẽ không hoạt động, các xác thực khác nhau được đặt trên mỗi điều khiển biểu mẫu, mỗi điều khiển biểu mẫu có lỗi, biểu mẫu thì không. Bạn cần lặp lại các điều khiển như Maximus đã đưa ra câu trả lời.
AJT82,

Tôi có thể truy cập vào các lỗi đối với từng cá nhân contorls như this.form.controls [ 'Email'] lỗi.
Nazrul Muhaimin

@ AJT_82 thực Form chính nó có thể hiển thị lỗi nếu một validator đã được thiết lập cho các formGroup (kiểm tra các tài liệu về lĩnh vực kiểm chứng chéo, mà làm cho tinh thần để validate trên nhóm và không nằm trong kiểm soát)
LookForAngular

3

Bây giờ, trong góc 9, bạn có thể sử dụng phương thức markAllAsTouched () để hiển thị các trình xác thực điều khiển không hợp lệ:

this.AddCustomerForm.markAllAsTouched();

Sẽ cho điểm +1 này, vì nó giúp tôi tìm ra những gì tôi cần biết --- nghĩa là hiển thị thông báo xác thực khi người dùng không nhất thiết phải chạm vào các đầu vào.
Sean Halls

1

Nếu bạn không có nhiều trường trong biểu mẫu, bạn có thể chỉ cần F12 và di chuột qua điều khiển, bạn sẽ có thể thấy cửa sổ bật lên với các giá trị nguyên sơ / chạm / hợp lệ của trường- "# fieldname.form-control.ng- không bị ảnh hưởng.ng-không hợp lệ ".


1

Tôi nghĩ bạn nên thử sử dụng this.form.updateValueAndValidity()hoặc thử thực hiện cùng một phương pháp đó trong mỗi điều khiển.


1

thử đi

 findInvalidControls(f: FormGroup) {
    const invalid = [];
    const controls = f.controls;
    for (const name in controls) {
      if (controls[name].invalid) {
        invalid.push(name);
      }
    }
    return invalid;
  }

1

Thao tác này sẽ ghi lại tất cả tên của các điều khiển 😊

for (let el in this.ReactiveForm.controls) {
      if (this.ReactiveForm.controls[el].errors) {
        console.log(el)
      }
 }          

bạn có thể tạo một mảng hoặc chuỗi từ này và hiển thị cho người dùng


0

Tôi đã tự do cải thiện mã AngularInDepth.com -s, để nó cũng tìm kiếm đệ quy các đầu vào không hợp lệ trong các biểu mẫu lồng nhau. Chung nó được lồng vào nhau bởi FormArray-s hoặc FormGroup-s. Chỉ cần nhập formGroup cấp cao nhất và nó sẽ trả về tất cả các FormControl không hợp lệ.

Bạn có thể bỏ qua một số kiểm tra kiểu "instanceof", nếu bạn muốn tách kiểm tra FormControl và bổ sung chức năng mảng không hợp lệ thành một chức năng riêng biệt. Điều này sẽ làm cho hàm trông gọn gàng hơn rất nhiều, nhưng tôi cần một tùy chọn toàn cục, một hàm, để có được một mảng phẳng gồm tất cả các formControl không hợp lệ và đây là giải pháp!

findInvalidControls( _input: AbstractControl, _invalidControls: AbstractControl[] ): AbstractControl[] {
    if ( ! _invalidControls ) _invalidControls = [];
    if ( _input instanceof FormControl  ) {
        if ( _input.invalid ) _invalidControls.push( _input );
        return _invalidControls;
    }

    if ( ! (_input instanceof FormArray) && ! (_input instanceof FormGroup) ) return _invalidControls;

    const controls = _input.controls;
    for (const name in controls) {
        let control = controls[name];
        switch( control.constructor.name )
        {
            case 'AbstractControl':
            case 'FormControl':
                if (control.invalid) _invalidControls.push( control );
                break;

            case 'FormArray':
                (<FormArray> control ).controls.forEach( _control => _invalidControls = findInvalidControls( _control, _invalidControls ) );
                break;

            case 'FormGroup':
                _invalidControls = findInvalidControls( control, _invalidControls );
                break;
        }
    }

    return _invalidControls;
}

Chỉ dành cho những người cần nó, vì vậy họ không phải tự mã hóa nó ..

Chỉnh sửa # 1

Nó đã được yêu cầu rằng nó cũng trả về FormArray-s và FormGroups không hợp lệ, vì vậy nếu bạn cũng cần điều đó, hãy sử dụng mã này

findInvalidControls( _input: AbstractControl, _invalidControls: AbstractControl[] ): AbstractControl[] {
    if ( ! _invalidControls ) _invalidControls = [];
    if ( _input instanceof FormControl  ) {
        if ( _input.invalid ) _invalidControls.push( _input );
        return _invalidControls;
    }

    if ( ! (_input instanceof FormArray) && ! (_input instanceof FormGroup) ) return _invalidControls;

    const controls = _input.controls;
    for (const name in controls) {
        let control = controls[name];
        if (control.invalid) _invalidControls.push( control );
        switch( control.constructor.name )
        {    
            case 'FormArray':
                (<FormArray> control ).controls.forEach( _control => _invalidControls = findInvalidControls( _control, _invalidControls ) );
                break;

            case 'FormGroup':
                _invalidControls = findInvalidControls( control, _invalidControls );
                break;
        }
    }

    return _invalidControls;
}

1
Tôi đã thử nó, nhưng nó không tìm thấy bất kỳ FormGroup hoặc FormArray không hợp lệ nào ... chỉ có FormControl không hợp lệ. Tôi đã mắc cùng một sai lầm ... hãy xem câu trả lời của tôi.
Jette

Tôi đã cải thiện câu trả lời của mình, để phù hợp với trường hợp sử dụng của bạn.
Karl Johan Vallner

0

bạn có thể ghi giá trị của biểu mẫu console.log(this.addCustomerForm.value), nó sẽ điều khiển tất cả giá trị của điều khiển sau đó các trường null hoặc "" (trống) cho biết điều khiển không hợp lệ

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.