Angular에서 다중 제어 사용자 지정 유효성 검사기 만들기
내 previous article about custom validators에서 언급했듯이 내장 유효성 검사기가 처리하지 않는 사용자 지정 논리를 처리하고 한 지점에서 유효성 검사 오류 메시지를 생성할 수 있도록 사용하는 것이 좋습니다. 이는 사용자 지정 유효성 검사기를 강력하고 재사용 가능하게 만듭니다.
다중 제어 사용자 지정 유효성 검사기 만들기
다중 컨트롤 사용자 지정 유효성 검사기를 만드는 것은 단일 컨트롤을 만드는 것과 매우 유사합니다. 유효성 검사기는 전달된 매개변수
AbstractControl
가 필요합니다. 단일 컨트롤 유효성 검사기에서 컨트롤은 일반적으로 FormControl
입니다. 그러나 다중 컨트롤 유효성 검사기의 경우 부모 FormGroup
를 컨트롤로 전달해야 합니다. 이렇게 하면 FormGroup
내부의 모든 하위 컨트롤 범위가 제공됩니다. 이 유효성 검사기를 보다 쉽게 재사용할 수 있도록 비교하려는 컨트롤의 이름도 전달합니다. 또한 오류 메시지를 보다 동적으로 만들기 위해 비교하는 값 종류의 이름을 전달할 수도 있습니다.그런 다음 양식 컨트롤의 값에 대한 변수를 만듭니다. 그것들이 있으면 몇 가지 간단한 조건을 설정합니다. 특정
FormGroup
대신 AbstractControl
로 FormControl
를 전달했기 때문에 FormControls
에 오류를 설정하려면 특정 컨트롤에서 setErrors()
을 호출해야 합니다. 그렇지 않으면 ValidationErrors
을 반환하면 FormGroup
에 적용되며 여기서 원하는 것이 아닙니다.export class MatchFieldValidator {
static validFieldMatch(
controlName: string,
confirmControlName: string,
fieldName: string = 'Password',
): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const controlValue: unknown | null = control.get(controlName)?.value;
const confirmControlValue: unknown | null = control.get(
confirmControlName,
)?.value;
if (!confirmControlValue) {
control.get(confirmControlName)?.setErrors({
confirmFieldRequired: `Confirm ${fieldName} is required.`,
});
}
if (controlValue !== confirmControlValue) {
control
.get(confirmControlName)
?.setErrors({ fieldsMismatched: `${fieldName} fields do not match.` });
}
if (controlValue && controlValue === confirmControlValue) {
control.get(confirmControlName)?.setErrors(null);
}
return null;
};
}
}
이제 작동하는 유효성 검사기가 있으므로 이를 구성 요소에 연결해야 합니다. 여러 개
FormControls
와 상호 작용하고 싶기 때문에 유효성 검사기를 부모FormGroup
에 연결해야 합니다. FormBuilder
은 유효성 검사기에 전달할 수 있는 제어 구성 뒤에 옵션 인수를 사용합니다. 일치 필드 유효성 검사기를 비교하려는 컨트롤의 이름 및 비교할 필드 종류와 함께 추가합니다. 관련된 내용에만 집중하기 위해 아래 코드를 단순화했습니다.private createForm(): FormGroup {
const form = this.fb.group({
password: [
'',
Validators.compose([PasswordValidator.validPassword(true)]),
],
confirmPassword: [''],
},
{
validators: Validators.compose([
MatchFieldValidator.validFieldMatch('password', 'confirmPassword', 'Password'),
]),
});
return form;
}
이제 작업 유효성 검사가 있으므로 오류를 템플릿에 바인딩할 수 있습니다. 단순함을 위해 여전히
KeyValuePipe
를 통해 오류 개체를 통해 루프를 사용하고 있습니다.<div class="field-group">
<mat-form-field>
<input
name="password"
id="password"
type="password"
matInput
placeholder="Password"
formControlName="password"
/>
<mat-error *ngIf="form.get('password')?.errors">
<ng-container *ngFor="let error of form.get('password')?.errors | keyvalue">
<div *ngIf="error.key !== 'required'">{{ error.value }}</div>
</ng-container>
</mat-error>
</mat-form-field>
<mat-form-field>
<input
name="confirmPassword"
id="confirmPassword"
type="password"
matInput
placeholder="Confirm Password"
formControlName="confirmPassword"
required
/>
<mat-error *ngIf="form.get('confirmPassword')?.errors">
<ng-container *ngFor="let error of form.get('confirmPassword')?.errors | keyvalue">
<div *ngIf="error.key !== 'required'">{{ error.value }}</div>
</ng-container>
</mat-error>
</mat-form-field>
</div>
유효성 검사기 테스트
다른 사용자 지정 유효성 검사기와 마찬가지로 다중 제어 사용자 지정 유효성 검사기를 쉽게 테스트할 수 있습니다. 이 유효성 검사기에 대한 단위 테스트를 작성하면 처음에는 처리하지 못했던 엣지 케이스를 찾고 처리하는 데 도움이 되었습니다. 다음은 몇 가지 예제 테스트입니다.
describe('validFieldMatch() default field name', () => {
const matchFieldValidator = MatchFieldValidator.validFieldMatch(
'controlName',
'confirmControlName',
);
const form = new FormGroup({
controlName: new FormControl(''),
confirmControlName: new FormControl(''),
});
const controlName = form.get('controlName');
const confirmControlName = form.get('confirmControlName');
it(`should set control error as { confirmFieldRequired: 'Confirm Password is required.' } when value is an empty string`, () => {
controlName?.setValue('');
confirmControlName?.setValue('');
matchFieldValidator(form);
const expectedValue = {
confirmFieldRequired: 'Confirm Password is required.',
};
expect(confirmControlName?.errors).toEqual(expectedValue);
});
it(`should set control error as { fieldsMismatched: 'Password fields do not match.' } when values do not match`, () => {
controlName?.setValue('password123!');
confirmControlName?.setValue('password123');
matchFieldValidator(form);
const expectedValue = {
fieldsMismatched: 'Password fields do not match.',
};
expect(confirmControlName?.errors).toEqual(expectedValue);
});
it(`should set control error as null when values match`, () => {
controlName?.setValue('password123!');
confirmControlName?.setValue('password123!');
matchFieldValidator(form);
expect(controlName?.errors).toEqual(null);
expect(confirmControlName?.errors).toEqual(null);
});
it(`should set control error as null when control matches confirm after not matching`, () => {
controlName?.setValue('password123!');
confirmControlName?.setValue('password123!');
matchFieldValidator(form);
controlName?.setValue('password123');
matchFieldValidator(form);
controlName?.setValue('password123!');
matchFieldValidator(form);
expect(controlName?.errors).toEqual(null);
expect(confirmControlName?.errors).toEqual(null);
});
it(`should set control error as null when confirm matches control after not matching`, () => {
controlName?.setValue('password123!');
confirmControlName?.setValue('password123!');
matchFieldValidator(form);
controlName?.setValue('password123');
matchFieldValidator(form);
confirmControlName?.setValue('password123');
matchFieldValidator(form);
expect(controlName?.errors).toEqual(null);
expect(confirmControlName?.errors).toEqual(null);
});
});
사용자 지정 유효성 검사기는 만들기 쉽고 매우 강력합니다. 모든 수준의 반응형에서 만들 수 있기 때문에 여러 컨트롤과 상호 작용할 수 있는 이와 같은 다중 컨트롤 사용자 지정 유효성 검사기를 만드는 것이 가능합니다. 이는 개발자가 사용자를 위해 매우 반응적인 UI/UX를 만드는 데 도움이 됩니다.
자원
저장소에는 원하는 동작을 입력하는 데 도움이 되는 unit tests for the validator이 포함되어 있습니다. Here은 GitHub의 리포지토리이고 here은 StackBlitz에 있는 코드의 작업 데모입니다. Angular의 모든 게시물에 태그가 지정되고 수집됩니다here .
게시물 Creating a Multi-Control Custom Validator in Angular이 Hapax Legomenon에 처음 나타났습니다.
Reference
이 문제에 관하여(Angular에서 다중 제어 사용자 지정 유효성 검사기 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/karvel/creating-a-multi-control-custom-validator-in-angular-if텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)