@ angular / forms 소스 코드 분석 Validators

우 리 는 @ angular / forms 패 키 지 는 주로 폼 문 제 를 해결 하 는 데 사용 되 는데 폼 문제 의 매우 중요 한 기능 은 폼 검사 기능 이라는 것 을 알 고 있 습 니 다.데이터 검증 은 매우 중요 합 니 다. 전단 이 백 엔 드 에 요청 하기 전에 데 이 터 를 검증 해 야 할 뿐만 아니 라 백 엔 드 가 전단 에서 보 낸 데이터 에 대해 서도 유효성 과 논리성 을 검증 해 야 합 니 다. 특히 데이터 베 이 스 를 저장 하기 전에 데이터 의 유효성 을 검증 해 야 합 니 다. @angular / forms 는 Validator 인 터 페 이 스 를 정의 하고 Required Validator, Checkbox Required Validator, Email Validator, MinLengthValidator, MaxLengthValidator, PatternValidator 여섯 개의 자주 사용 하 는 검사 명령 을 내장 하여 모든 vaidator 가 Validator 인 터 페 이 스 를 실현 했다.이 검사 명령 의 사용 은 매우 간단 합 니 다. 예 를 들 어 Email Validator 와 Required Validator 명령 을 사용 하여 입력 한 데 이 터 를 email 로 검사 하고 비어 있 으 면 안 됩 니 다.

이렇게 입력 한 이메일 형식 이 아니라면 Email Validator 명령 은 오 류 를 검사 하고 host (여기 서 input 요소) 에 'ng - invalid' class 를 추가 합 니 다. 그러면 개발 자 는 이 class 에 css 효 과 를 추가 하여 사용자 체험 을 향상 시 킬 수 있 습 니 다.그렇다면 내부 운행 과정 은 어 떨 까?
실제로 위의 demo 에는 NgModel 명령 뿐만 아니 라 Email Validator 와 Required Validator 두 개의 vaidators 명령 도 연결 되 어 있 습 니 다.명령 은 예화 할 때 성명 순서에 따라 순서대로 진행 되 고 의존 하 는 명령 이 있 으 면 설치 한 후에 Forms Module 은 먼저 Required Validator 명령 을 성명 한 다음 에 Email Validator 명령 이 고 마지막 에 NgModel 이 므 로 예화 순 서 는 Required Validator - > Email Validator - > NgModel 이 며 NgModel 은 NG 에 의존 하기 때문이다.VALIDATORS, 그래서 NgModel 성명 이 앞 에 있어 도 뒤에 실례 화 됩 니 다.Required Validator 와 Email Validator 는 실례 화 과정 에서 모두 REQUIRED 를 제공 합 니 다.VALIDATOR 와 EMAILVALIDATOR 두 서비스, 그리고 Static Provider 의 multi 속성 을 true 로 설정 하면 여러 개의 의존 서비스 (여 기 는 Required Validator 와 Email Validator 대상) 가 하나의 토 큰 (여 기 는 NG VALIDATORS) 을 공용 할 수 있 습 니 다. multi 속성 작용 은 소스 코드 에서 설명 할 수 있 습 니 다.NgModel 이 실례 화 될 때 그 구 조 는 @ Self () NG 에 의존한다VALIDATORS, @ Self () 는 NgModel 명령 에 마 운 트 된 숙주 요소 에서 이 토 큰 이 가지 고 있 는 서 비 스 를 찾 아 보라 고 했 습 니 다. NgModel 은 NG 를 제공 하지 않 았 습 니 다.VALIDATORS, 하지만 input 숙주 요소 에 마 운 트 된 REQUIREDVALIDATOR 와 EMAILVALIDATOR 는 이 서 비 스 를 제공 하기 때문에 NgModel 의 의존 vaidators 는 이 두 명령 으로 구 성 된 대상 배열 이다.
NgModel 은 실례 화 할 때 부모 컨트롤 용기 가 없 기 때문에 호출setUpStandalone () 을 사용 하여 setUpControl () 방법 으로 FormControl 대상 의 동기 화 vaidator 의존 도 를 설정 합 니 다 (비동기 vaidator 의존 도 있 으 면 마찬가지 입 니 다). 이 의존 도 는 Validators. copose () 를 호출 하여 돌아 오 는 ValidatorFn 함수 입 니 다.Validators. compose () 매개 변 수 는 NgModel. vaidator 를 호출 합 니 다. 즉, composeValidators 를 호출 하여 ValidatorFn 을 얻 고 내부 에 서 는 normalizeValidator () 함 수 를 (AbstractControl) = > Validator. vaidate () 로 변환 합 니 다.그래서 input 컨트롤 과 연 결 된 FormControl 대상 에 동기 화 vaidator 데이터 검사 기 가 있 습 니 다.그러면 input 입력 상자 에 데 이 터 를 입력 할 때 검사 기 는 언제 실 행 됩 니까?
NgModel 실례 화 시 보기 데이터 업데이트 리 셋 도 설치 되 어 있 습 니 다. 그러면 input 보기에 있 는 데이터 가 업 데 이 트 될 때 이 리 셋 이 실 행 됩 니 다. 이 리 셋 은 FormControl 의 value 값, 즉 FormControl. setValue () 함 수 를 업데이트 하고 내부 에 updateValueAndValidity 를 호출 하여 데이터 검사 기 를 실행 합 니 다.위의 글 에서 FormControl 의 vaidator 의존 은 실제 Validators. copose () 가 되 돌아 오 는 함수 이기 때문에 이 반전 함 수 를 실행 합 니 다. 이 presentaValidators 는 (AbstractControl) = > Required Validator. vaidate () 와 (AbstractControl) = > Email Validator. vaidator () 로 구 성 된 배열 입 니 다. 그리고 이 두 Validator 의 vaidate () 를 순서대로 실행 합 니 다.함수검사 오류 가 발생 하면 ValidationErrors 를 되 돌려 줍 니 다. 예 를 들 어 이메일 검사 기 는 {'email': true} 을 되 돌려 줍 니 다.여기 서 주의해 야 할 것 은 Validator 명령 의 vaidate () 함수 가 실제 적 으로 Validator 류 에 대응 하 는 정적 함 수 를 호출 하 는 지 하 는 것 입 니 다. 그러면 검증 기 명령 은 템 플 릿 에서 직접 사용 할 수 있 고 Validator 류 의 정적 함 수 는 응답 식 폼 에서 사용 할 수 있 습 니 다.검사 기 가 실 행 된 후 FormControl. errors 속성 을 설정 하여 FormControl 의 status 속성 을 계산 합 니 다. 검사 오류 가 발생 하면 status 속성 값 은 INVALID 입 니 다.검사 가 잘못 되면 input 의 class 는 왜 'ng - invalid' 를 추가 합 니까?실제 Ng Control Status 명령 도 이 input 요 소 를 연결 하고 있 기 때문에 이 명령 의 의존 도 는 현재 마 운 트 된 숙주 요소 에서 NgControl 을 찾 습 니 다. 이 demo 에서 NgModel 명령 입 니 다. NgControl Status 명령 의 host 속성 중의 '[class. ng - invalid]': 'ngClassInvalid' 는 ngClassInvalid () 함 수 를 실행 하여 'ng - invalid' class 가 있 는 지 판단 합 니 다.검사 오류 가 발생 했 을 때 이 함수 의 실행 결 과 는 true 입 니 다. FormControl. invalid 속성 을 읽 었 기 때문에 'ng - invalid' class 는 input 요소 에 추 가 됩 니 다.마찬가지 로 다른 클 라 스, 예 를 들 어 pending, dirty 등 도 마찬가지다.이렇게 하면 검사 기의 전체 운행 과정 을 이해 할 수 있 습 니 다. 왜 오 류 를 검사 할 때 컨트롤 상 태 를 설명 하 는 'ng - invalid' class 를 자동 으로 추가 하 는 지 포함 합 니 다.
Validators 의 내부 운행 절 차 를 이 해 했 습 니 다. 사용자 정의 Validator 를 쓰 는 것 은 간단 합 니 다. (물론 사용자 정의 Validator 를 쓰 는 것 은 Validator 내부 운행 원 리 를 알 필요 가 없습니다.)예 를 들 어 사용자 정의 검사 기 ForbiddenValidator 를 쓰 고 input 입력 내용 에 일부 문자열 이 있 으 면 안 됩 니 다. @ angular / forms 에 내 장 된 검사 기 MinLengthValidator 를 모방 할 수 있 습 니 다.
import {Validators as FormValidators} from '@angular/forms';

export class Validators extends FormValidators {
  static forbidden(forbidden: string): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      return (new RegExp(forbidden)).test(control.value) ? {forbidden: true} : null;
    }
  }
}

export const FORBIDDEN_VALIDATOR: StaticProvider = {
  provide: NG_VALIDATORS,
  useExisting: forwardRef(() => ForbiddenValidator),
  multi: true
};

@Directive({
  selector:
    ':not([type=checkbox])[forbidden][formControlName],:not([type=checkbox])[forbidden][formControl],:not([type=checkbox])[forbidden][ngModel]',
  providers: [FORBIDDEN_VALIDATOR],
})
export class ForbiddenValidator implements Validator{
  private _onChange: () => void;
  private _validator: ValidatorFn;
  
  @Input() forbidden: string;
  
  ngOnChanges(changes: SimpleChanges) {
    if ('forbidden' in changes) {
      this._createValidator();
      if (this._onChange) this._onChange();
    }
  }
  
  registerOnValidatorChange(fn: () => void): void {
    this._onChange = fn;
  }
  
  validate(c: AbstractControl): ValidationErrors | null {
    return this.forbidden ? this._validator(c) : null;
  }
  
  private _createValidator(): void {
    this._validator = Validators.forbidden(this.forbidden);
  }
}

이렇게 하면 구성 요소 템 플 릿 에서 사용 할 수 있 습 니 다:
@Component(
{
    template: `
        

Template-Driven Form

Reactive-Driven Form

Update Forbidden Text

` }) export class AppComponent { // custom validator forbiddenText = 'test'; email = '[email protected]'; emailFormControl = new FormControl('[email protected]', [Validators.forbidden(this.forbiddenText)]); }

전체 코드 는 stackblitz demo 를 참조 할 수 있 습 니 다.
따라서 Validator 내부 운행 원 리 를 이해 한 후에 사용자 정의 Validator 만 쓸 수 있 습 니 다. 이 Validator 는 템 플 릿 구동 폼 에 도 사용 할 수 있 고 응답 식 폼 에 도 사용 할 수 있 습 니 다. 왜 그렇게 써 야 하 는 지 알 수 있 습 니 다. 이것 은 매우 중요 합 니 다!
또한 @ angular / forms 관련 글 을 읽 고 NgModel 의 양 방향 바 인 딩 내부 원 리 를 알 수 있 습 니 다. @ angular / forms 소스 코드 해석 의 양 방향 바 인 딩 입 니 다.

좋은 웹페이지 즐겨찾기