UFO ET IT

Angular 4 반응 형으로 잘못된 컨트롤을 찾는 방법

ufoet 2021. 1. 13. 07:27
반응형

Angular 4 반응 형으로 잘못된 컨트롤을 찾는 방법


Angular에는 아래와 같은 반응 형이 있습니다.

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는 false를 반환하지만 모든 것이 좋아 보입니다.

컨트롤 컬렉션의 상태 속성을 확인하여 찾으려고 노력했습니다. 그러나 유효하지 않은 것을 찾아서 사용자에게 표시하는 방법이 있는지 궁금합니다.


모든 컨트롤을 반복하고 상태를 확인할 수 있습니다.

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

방금이 문제에 맞서 싸웠습니다. 모든 양식 필드는 유효하지만 양식 자체는 여전히 유효하지 않습니다.

컨트롤이 동적으로 추가 / 제거되는 FormArray에 'Validator.required'를 설정 한 것으로 나타났습니다. 따라서 FormArray가 비어 있어도 여전히 필요했기 때문에 보이는 모든 컨트롤이 올바르게 채워져 있어도 양식은 항상 유효하지 않았습니다.

내 'findInvalidControls'함수는 FormGroup / FormArray가 아닌 FormControl 만 확인했기 때문에 양식의 잘못된 부분을 찾지 못했습니다. 그래서 나는 그것을 약간 업데이트했습니다.

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

폼과 모든 컨트롤 모두 각도 클래스 AbstractControl을 확장합니다. 각 구현에는 유효성 검사 오류에 대한 접근자가 있습니다.

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

API 문서에는 모든 참조 https://angular.io/api/forms/AbstractControl이 포함되어 있습니다.

편집하다

나는 오류 접근자가 이런 식으로 작동한다고 생각했지만 github에 대한이 링크는 내가 한 것처럼 생각한 다른 사람들이 있음을 보여줍니다 https://github.com/angular/angular/issues/11530

어쨌든 컨트롤 접근자를 사용하여 양식의 모든 formControl을 반복 할 수 있습니다.

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

양식에 필드가 많지 않은 경우 F12를 누르고 컨트롤 위로 마우스를 가져 가면 필드의 원래 / 손상된 / 유효한 값이있는 팝업을 볼 수 있습니다. "# fieldname.form-control.ng- untouched.ng-invalid "입니다.


저는 AngularInDepth.com -s 코드 를 개선 할 자유를 얻었 으므로 중첩 된 형식에서도 유효하지 않은 입력을 재귀 적으로 검색합니다. FormArray-s 또는 FormGroup-s에 의해 중첩되는지 여부. 최상위 formGroup을 입력하면 유효하지 않은 모든 FormControl이 반환됩니다.

You can possibly skim some of the "instanceof" type checks away, if you would separate the FormControl check and addition to invalid array functionality into a separate function. This would make the function look a lot cleaner, but I needed a global, single function, option to get a flat array of all the invalid formControls and this is the solution!

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

Just for those that need it, so they don't have to code it themselves..

Edit #1

It was requested that it also returns invalid FormArray-s and FormGroups, so if you need that also, use this code

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

you can log value of form console.log(this.addCustomerForm.value), it will console all control's value then null or ""(empty) fields indicate invalid controls

ReferenceURL : https://stackoverflow.com/questions/45220073/how-to-find-the-invalid-controls-in-angular-4-reactive-form

반응형