codememo

각도 - 동적으로 검증자 추가/제거

tipmemo 2023. 8. 11. 21:51
반응형

각도 - 동적으로 검증자 추가/제거

나는 있습니다FormGroup아래와 같이 정의됨:

this.businessFormGroup: this.fb.group({
    'businessType': ['', Validators.required],
    'description': ['', Validators.compose([Validators.required, Validators.maxLength(200)])],
    'income': ['']
  })

이제 언제businessType이라Other제거합니다.Validators.required의 검증자.description그리고 만약에businessType아닙니다Other나는 다시 추가하고 싶습니다.Validators.required.

아래 코드를 사용하여 동적으로 추가/제거합니다.Validators.required그러나 기존 데이터를 삭제합니다.Validators.maxLength검증인

if(this.businessFormGroup.get('businessType').value !== 'Other'){
    this.businessFormGroup.get('description').validator = <any>Validators.compose([Validators.required]);               
} else {                
    this.businessFormGroup.get('description').clearValidators();               
}

this.businessFormGroup.get('description').updateValueAndValidity(); 

제 질문은 다음과 같습니다. 기존 검증자를 추가/제거할 때 어떻게 유지할 수 있습니까?required검증인

Angular 12.2 이상을 사용하는 경우 다음을 사용할 수 있습니다.AbstractControl방법들addValidators,removeValidators,그리고.hasValidator문서에 따라:

if(this.businessFormGroup.get('businessType').value !== 'Other'){
    this.businessFormGroup.get('description').addValidators(Validators.required);               
} else {                
    this.businessFormGroup.get('description').clearValidators();               
}

이전 버전의 경우 Angular 양식에는 Validators()를 프로그래밍 방식으로 할당할 수 있는 내장 함수 집합 Validators()가 있습니다.그러나 이렇게 하면 검증자를 덮어씁니다.

예를 들어 다음을 수행할 수 있습니다.

if(this.businessFormGroup.get('businessType').value !== 'Other'){
    this.businessFormGroup.controls['description'].setValidators([Validators.required, Validators.maxLength(200)]);              
} else {                
    this.businessFormGroup.controls['description'].setValidators([Validators.maxLength(200)]);               
}
this.businessFormGroup.controls['description'].updateValueAndValidity();

방법을 사용하면 기존 검증자를 덮어쓰므로 재설정하는 제어에 필요하거나 원하는 모든 검증자를 포함해야 합니다.

이것은 나에게 효과가 있습니다.

onAddValidationClick(){
    this.formGroup.controls["firstName"].setValidators(Validators.required);
    this.formGroup.controls["firstName"].updateValueAndValidity();
}

onRemoveValidationClick(){
    this.formGroup.controls["firstName"].clearValidators();
    this.formGroup.controls["firstName"].updateValueAndValidity();
}

확인란을 사용하여 "확인 필요"를 두 번 이상 변경하는 경우 다음을 추가해야 합니다.

this.formGroup.controls["firstName"].setErrors(null);

그래서:

  onAddValidationClick(){
         this.formGroup.controls["firstName"].setValidators(Validators.required);
        this.formGroup.controls["firstName"].updateValueAndValidity();
      }

onRemoveValidationClick(){
         this.formGroup.controls["firstName"].setErrors(null);
         this.formGroup.controls["firstName"].clearValidators();
        this.formGroup.controls["firstName"].updateValueAndValidity();
      }

단순한 접근 방식은 조건부 변수가 변경될 때마다 컨트롤의 검증자를 설정하는 것입니다.하지만 우리는 실제로 간접 + 기능적 프로그래밍을 사용함으로써 그것보다 더 잘 할 수 있습니다.

의 존재를 고려합니다.descriptionIsRequired게터, 그것은 부란 깃발 역할을 합니다.

아이디어:

  • 다음을 수행하는 사용자 지정 검증자 함수를 만듭니다.descriptionIsRequired인수로 지정하고 이에 따라 필수 + maxLength 또는 maxLength에 대한 컨트롤의 유효성을 검사합니다.
  • 컨트롤의 유효성이 평가될 때 최신 값이 다음과 같은 방식으로 사용자 정의 검증기를 설명 컨트롤에 바인딩합니다.descriptionIsRequired고려해야 합니다.

첫 번째 요점은 구현하기에 매우 간단합니다.

function descriptionValidator(required: boolean): ValidatorFn {
  return (formControl: FormControl): ValidationErrors => {
    if (required) {
      return Validators.compose([Validators.required, Validators.maxLength(200)])(formControl);
    } else {
      return Validators.maxLength(200)(formControl);
    }
  }
}

이 기능은 자체 캡슐화된 기능입니다.

두 번째 요점은 조금 더 까다롭지만 결국에는 다음과 같습니다.

export class FooComponent {
  constructor(){
    this.form = fb.group({
      description: ['initial name', this.validator()]
    });
  }

  private get descriptionIsRequired(): boolean {
   ...
  }

  private validator(): ValidatorFn {
    return (c: FormControl): ValidationErrors => descriptionValidator(this.descriptionIsRequired)(c);
  }
}

무슨 일이 일어나고 있는지에 대한 작은 설명:

  • validator메소드는 함수를 반환합니다.
  • 에 의해 반환된 함수validator공장 방식으로 간주될 수 있습니다. 호출될 때마다 새로운 함수, 더 구체적으로는 새로운 인스턴스를 반환합니다.descriptionValidator최신 버전을 사용하여descriptionIsRequired가치.

다음 스택블리츠의 라이브 데모

이것이 도움이 될 수도 있습니다.

"의 Validator 에 Validator.required를 추가하는 입니다.AbstractControl:

if (c.validator !== null) {
        c.setValidators([c.validator, Validators.required])
  } else {
        c.setValidators([Validators.required])
  }

아직 답을 찾고 있는 사람은 이렇게 하면 됩니다. OnInit()에서 처리하거나 원하는 장소에서 처리할 수 있습니다.

   const validators = formGroup.validator; /* or control.validator */

   const newValidator = CustomValidator.checkUserNameValidity(); 

   /* Add to existing validator */

   if(validator) {
      formGroup.setValidators([validators, newValidator])
   } else {. /* if no validators added already */
      formGroup.setValidators([newValidator]);
   }

asyncValidator에 대해서도 동일한 작업을 수행합니다.

확인란을 사용하여 "확인 필요"를 두 번 이상 변경하는 경우 다음을 추가해야 합니다.매우 중요한 분야! 이것.formGroup.controls["firstName"]입니다.오류 설정(null);

컨텍스트에 따라 일부 값이 필요하지만 다른 값에서는 생략할 수 있는 양식이 있습니다.저의 경우 'mainform.updateValueAndValidity()'를 호출하기에는 충분하지 않았습니다.유효성 검사 요구를 동적으로 설정할 때 해당 필드를 명시적으로 업데이트해야 했습니다.

formField.setValidators([RxwebValidators.required()]);
formField.updateValueAndValidity({onlySelf: true});

키가 {onlySelf:true}이었습니다.

언급URL : https://stackoverflow.com/questions/49075027/angular-dynamically-add-remove-validators

반응형