티스토리 뷰
Angular : Password Validator 구현 사용자 정의 Validator 1
Korean Eagle 2020. 6. 21. 11:051. 하나의 form control을 검증하는 게 아닌 form 전체에 대한 검증에 대한 포스트이다.
1-1 Java의 경우에도 Annoation을 생성하여 Form Control 상호 검증이 가능한데 유사한 개념이다.
1-2 javascript(typescript)의 경우는 functional programming 태생이라 간단히 함수만 추가로 구현하면 된다.
1-3 typescript는 interface를 사용하면 간결하기 때문에 많이 사용하는데, 웃긴건 너무 많이 너무 타입이 많다.
1-3-1 그래서 타입 정의 찾아다닌다고 짜증나는 경우가 생긴다.
2. 프로젝트를 하나 생성하고 검증을 구현할 컴포넌트 하나를 생성한다.
2-1 이제 template을 작성한다.
2-1-1 passwordconfirm.component.html이다.
<div class="container">
<form [formGroup]="passwordFormGroup">
<div class="form-group">
<label for="password" class="form-label">Password</label>
<input type="text" class="form-control" id="password" formControlName="password">
</div>
<div class="form-group">
<label for="passwordConfirmation" class="form-label">Password Confirmation</label>
<input type="text" class="form-control" id="passwordConfirmation" formControlName="passwordConfirmation">
</div>
</form>
</div>
<hr>
<div>Form is valid: {{ passwordFormGroup.valid }}</div>
<div>Form values: {{ passwordFormGroup.value | json }}</div>
<div>Form errors: {{ passwordFormGroup.errors | json }}</div>
2-1-2 이 컴포넌트를 사용하는 app 컴포넌트 template을 작성한다.
<div>Form is valid: {{ addition.valid }}</div>
<div>Form values: {{ addition.value | json }}</div>
<div>Form errors: {{ addition.errors | json }}</div>
<hr>
<app-passwordconfirm></app-passwordconfirm>
3. custom 검증함수 추가하기
3-1 ReactiveFormsModule은 2가지의 form group 생성방식을 제공한다.
3-1-1 첫번째는 FormGroup, FormControl을 사용하는 방법이고
3-1-2 두번째는 FormBuilder를 사용하는 방법이다.
3-2 첫번째 방식
3-2-1 아래처럼 기본 껍데기를 구현한다. 그리고 fornGroup의 생성자의 두번째 인자를 추가한다.
export class PasswordconfirmComponent implements OnInit {
passwordFormGroup = new FormGroup({
password: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
]),
passwordConfirmation: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
]),
}, );
3-2-2 첫번째 인자 객체뒤에 , 를 추가하면 화면이 뜬다. 어디에 검증로직을 추가하는지가 제일 중요하다.
3-2-2-1 내용은 ValidatorFn | ValidatorFn[] | AbstractControlOptions 타입의 함수를 제공하라는 의미다.
3-2-2-2 이 예제의 경우 하나의 함수만 있으면 되니 굳이 []를 사용하지 않고 그냥 함수를 넣으면 된다.
3-2-3-3 한가지 더 말하고 싶은 부분은 세번째 인자인데 것은 비동기식 검증함수이다.
3-2-3-3-1 즉 서버와 통신 후에 검증 결과를 Observable을 통해 전달하는 방식이다.
3-2-3 간단한 비밀번호 검증함수를 추가한다.
3-2-3-0 AbstractControl은 FormControl, FormGroup의 추상클래스이다.
3-2-3-1 단순히 두 FormControl의 값을 비교하여 다르면 notMatched 속성을 추가하고 같으면 null을 반환한다.
3-2-3-2 반환하는 ValidationErrors는 단순한 객체정의로 key만 문자열이면 되는 단순한 객체이다.
import { Component, OnInit } from '@angular/core';
import {
FormGroup,
Validators,
AbstractControl,
ValidationErrors,
FormControl,
} from '@angular/forms';
@Component({
selector: 'app-passwordconfirm',
templateUrl: './passwordconfirm.component.html',
styleUrls: ['./passwordconfirm.component.css'],
})
export class PasswordconfirmComponent implements OnInit {
passwordFormGroup = new FormGroup(
{
password: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
]),
passwordConfirmation: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
]),
},
(form: AbstractControl): ValidationErrors => {
const { password, passwordConfirmation } = form.value;
if (password !== passwordConfirmation) {
return { notMatched: true };
} else {
return null;
}
}
);
ngOnInit(): void {}
}
3-2-4 결과화면
3-3 두번째 Form Builder 사용하는 경우
3-3-1 아래처럼 동일하게 기본 코드를 작성한다.
import { Component, OnInit } from '@angular/core';
import {
FormGroup,
FormBuilder,
Validators,
AbstractControl,
ValidationErrors,
FormControl,
} from '@angular/forms';
@Component({
selector: 'app-passwordconfirm',
templateUrl: './passwordconfirm.component.html',
styleUrls: ['./passwordconfirm.component.css'],
})
export class PasswordconfirmComponent implements OnInit {
ngOnInit(): void {}
passwordFormGroup: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.passwordFormGroup = this.formBuilder.group(
{
password: [
'',
[
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
],
],
passwordConfirmation: [
'',
[
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
],
],
}, );
}
}
3-3-2 첫번째 방식과 동일하게 첫번째 인자 뒤에서 , 를 입력하면 vscode에서는 도움창이 뜬다.
3-3-2-1 첫번째 방식과는 다르게 인자가 3개가 아니고 2개이다.
3-3-2-1-1 하나의 인자객체로 동기, 비동기를 다 처리하겠다는 뜻이다.
3-3-2-1-1-1 그 인자는 AbstractContolOptions이나 일반적인 객체를 받는다고 한다.
3-3-2-1-2 설명을 좀 더 보면 두 가지의 경우 어떤 속성을 제공해야 하는지 명시하고 있다.
3-3-2-1-2-1 두 경우 모두 validators, asyncValidator 속성이 있어 위에서 말한 첫번째 방식 인자와 동일하다.
3-3-2-1-2-2 사실 첫번째 방식과 동일한데 인자를 받는 방식만 다를 뿐이다.
3-3-3 이제 간단한 검증로직을 아래처럼 구현한다. 동기화 검증로직이니 validator 속성을 사용하면 된다.
3-3-3-1 아래의 경우는 validator 속성에 배열을 사용했지만, 사실 하나밖에 없으니 []을 제거해도 동일하다..
import { Component, OnInit } from '@angular/core';
import {
FormGroup,
FormBuilder,
Validators,
AbstractControl,
} from '@angular/forms';
@Component({
selector: 'app-passwordconfirm',
templateUrl: './passwordconfirm.component.html',
styleUrls: ['./passwordconfirm.component.css'],
})
export class PasswordconfirmComponent implements OnInit {
ngOnInit(): void {}
passwordFormGroup: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.passwordFormGroup = this.formBuilder.group(
{
password: [
'',
[
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
],
],
passwordConfirmation: [
'',
[
Validators.required,
Validators.minLength(3),
Validators.maxLength(20),
],
],
},
{
validators: [
(form: AbstractControl) => {
const { password, passwordConfirmation } = form.value;
if (password !== passwordConfirmation) {
return { notMatched: true };
} else {
return null;
}
},
],
}
);
}
}
3-3-4 결과화면 - 첫번째 방식과 결과는 동일하다.
3-4 어떤 방식으로 구현해도 상관없다. 어차피 결과는 동일하다.
3-4-1 다만 builder의 경우 생성할 때 좀 더 신경쓸게 적다는 장점이 있어 내가 선호할 분이다.
'Client Technologies > Angular' 카테고리의 다른 글
Angular : Form Validation 상태 구독하기 1 - 기본 검증로직 작성 (0) | 2020.06.22 |
---|---|
Angular : Password Validator 구현 사용자 정의 Validator 2 (0) | 2020.06.21 |
Angular : 재활용 가능한 Reactive Forms, ngx-mask 5. 테두리 테마 적용과 제출 버튼 비활성화 (0) | 2020.06.17 |
Angular : 재활용 가능한 Reactive Forms, ngx-mask 4. form 에러처리하기 (0) | 2020.06.17 |
Angular : 재활용 가능한 Reactive Forms, ngx-mask 3. form 생성 및 화면 매핑하기 (0) | 2020.06.17 |
- Total
- Today
- Yesterday
- 도커 개발환경 참고
- AWS ARN 구조
- Immuability에 관한 설명
- 자바스크립트 멀티 비동기 함수 호출 참고
- WSDL 참고
- SOAP 컨슈머 참고
- MySql dump 사용법
- AWS Lambda with Addon
- NFC 드라이버 linux 설치
- electron IPC
- mifare classic 강의
- go module 관련 상세한 정보
- C 메모리 찍어보기
- C++ Addon 마이그레이션
- JAX WS Header 관련 stackoverflow
- SOAP Custom Header 설정 참고
- SOAP Custom Header
- SOAP BindingProvider
- dispatcher 사용하여 설정
- vagrant kvm으로 사용하기
- git fork, pull request to the …
- vagrant libvirt bridge network
- python, js의 async, await의 차이
- go JSON struct 생성
- Netflix Kinesis 활용 분석
- docker credential problem
- private subnet에서 outbound IP 확…
- 안드로이드 coroutine
- kotlin with, apply, also 등
- 안드로이드 초기로딩이 안되는 경우
- navigation 데이터 보내기
- 레이스 컨디션 navController
- raylib
- RestTemplate
- mapping
- 외부파일
- MYSQL
- form
- Angular
- Rest
- hibernate
- Spring
- one-to-one
- Security
- 자바
- 상속
- login
- 매핑
- Spring Security
- one-to-many
- WebMvc
- 설정
- jsp
- crud
- 스프링부트
- 설정하기
- XML
- 로그인
- Validation
- Many-To-Many
- 스프링
- 하이버네이트
- spring boot