-
03 폼 유효성검사 03앵귤러/04 폼(Forms) 2017. 9. 24. 17:41
사용자정의 유효성검사기
내장 유효성 검사기가 응용프로그램의 정확한 사용사례와 항상 일치하지는 않기 때문에 사용자 정의 유효성검사기를 만드는 것이 좋습니다.
이 가이드의 이전 예제에서 forbiddenNameValidator 함수를 보겠습니다. 이 함수의 정의는 다음과 같습니다.
shared/forbidden-name.directive.ts (forbiddenNameValidator)
/** A hero's name can't match the given regular expression */
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} => {
const forbidden = nameRe.test(control.value);
return forbidden ? {'forbiddenName': {value: control.value}} : null;
};
}
이 함수는 특정 금지된 이름을 탐지하기 위해 정규표현식을 사용하고 유효성검사기 함수를 리턴하는 팩토리입니다.
이 샘플에서 금지된 이름은 "bob"이므로 유효성검사기는 "bob"이 포함된 영웅이름을 거부합니다. "alice"또는 구성하는 정규식에 일치하는 이름을 거부할 수도 있습니다.
forbiddenNameValidator 팩토리는 구성된 유효성검사기 함수를 리턴합니다. 이 함수는 Angular 컨트롤 객체를 사용하여 제어 값이 유효하면 null을 리턴하고, 그렇지 않으면 유효성검사 오류객체를 리턴합니다. 유효성검사 오류 객체는 일반적으로 이름이 유효성검사 키인 'forbiddenName'이며 값을 오류 메시지 {name}에 삽입할 수 있는 임의의 값 사전입니다.
반응형 폼에 추가하기
반응형 폼에서는 사용자정의 유효성검사기를 추가하는 것이 매우 간단합니다. 함수를 직접 FormControl에 전달하면 됩니다.
reactive/hero-form-reactive.component.ts (validator functions)
this.heroForm = new FormGroup({
'name': new FormControl(this.hero.name, [
Validators.required,
Validators.minLength(4),
forbiddenNameValidator(/bob/i) // <-- Here's how you pass in the custom validator.
]),
'alterEgo': new FormControl(this.hero.alterEgo),
'power': new FormControl(this.hero.power, Validators.required)
});
템플릿 기반 양식에 추가하기
템플릿 기반 폼에서는 FormControl 인스턴스에 직접 액세스할 수 없으므로 반응형 폼에서처럼 유효성 검사기를 전달할 수 없습니다. 대신 템플릿에 디렉티브를 추가해야합니다.
해당 ForbiddenValidatorDirective는 forbiddenNameValidator 주위의 래퍼 역할을 합니다.
Angular는 유효성검사 프로세스에서 디렉티브의 역할을 인식합니다. 이 디렉티브는 NG_VALIDATORS 공급자와 자체적으로 등록되기 때문입니다. 공급자에는 확장가능한 유효성검사기 모음이 있습니다.
shared/forbidden-name.directive.ts (providers)
providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
그런 다음 디렉티브 클래스는 Validator 인터페이스를 구현하므로 Angular 폼과 쉽게 통합 할 수 있습니다. 다음의 나머지 부분은 어떻게 모든 것을 함께 제공하는지 아이디어를 얻는 데 도움이될 디렉티브 입니다.
shared/forbidden-name.directive.ts (directive)
@Directive({
selector: '[forbiddenName]',
providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
})
export class ForbiddenValidatorDirective implements Validator {
@Input() forbiddenName: string;
validate(control: AbstractControl): {[key: string]: any} {
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
: null;
}
}
ForbiddenValidatorDirective가 준비되면 셀렉터에 forbiddenName을 모든 입력 엘리먼트에 추가하기 만하면됩니다. 예:
template/hero-form-template.component.html (forbidden-name-input)
<input id="name" name="name" class="form-control"
required minlength="4" forbiddenName="bob"
[(ngModel)]="hero.name" #name="ngModel" >
사용자 정의 유효성검사 디렉티브는 useClass 대신 useExisting을 사용하여 인스턴스화되었음을 알수 있습니다. 등록된 유효성검사기는 ForbiddenValidatorDirective의 인스턴스 여야하며, forbiddenName 프로퍼티가 "bob"에 바인딩된 폼의 인스턴스 여야합니다. useExisting을 useClass로 바꾸려면 새 클래스 인스턴스를 등록해야합니다. 이것은 forbiddenName이 없습니다.
'앵귤러 > 04 폼(Forms)' 카테고리의 다른 글
04 리액티브 폼(Reactive Forms) 01 (0) 2017.10.02 03 폼 유효성검사 04 (0) 2017.09.24 03 폼 유효성검사 02 (0) 2017.09.24 03 폼 유효성검사 01 (0) 2017.09.24 02 템플릿기반 폼(Template-driven Forms) 06 (0) 2017.09.03