DevGang
Авторизоваться

Angular — проверка нескольких полей (перекрестное поле) с формами, управляемыми шаблонами

Учебник, созданный с использованием Angular 15.1.5 и форм, управляемых шаблонами

Это краткий пример того, как реализовать перекрестную проверку полей в Angular для сравнения и проверки нескольких полей с помощью форм, управляемых шаблонами. Для более подробного примера регистрационной формы, которая включает в себя множество других полей, см. Angular 14 — пример проверки формы на основе шаблона.

https://stackblitz.com/edit/angular-template-driven-forms-cross-field-validation

Шаблон компонента Angular с проверкой перекрестного поля

Шаблон компонента приложения содержит пример формы с двумя полями ввода для password и confirmPassword. Оба поля помечены как обязательные директивой required валидатора, поле password имеет директиву minlength, установленную на шесть символов, а пользовательская директива валидатора [mustMatch] прикреплена к родительской форме для сравнения двух полей пароля, чтобы убедиться, что они оба имеют такое же значение.

Событие отправки формы привязано к методу onSubmit() компонента приложения с привязкой события (ngSubmit)="onSubmit(f)". Переменная шаблона #f="ngForm" создает экземпляр FormGroup для предоставления доступа к данным формы и статусу проверки в компоненте приложения.

Валидаторы и директивы в шаблонных формах

Проверка осуществляется с помощью функций проверки, которые присоединяются к полям или формам с помощью директив в формах, управляемых шаблонами. Валидаторы required и валидаторы minlength включены в структуру Angular, валидатор mustMatch — это настраиваемый валидатор для добавления поддержки проверки перекрестных полей.

Поля ввода, зарегистрированные в родительской форме

Каждое поле ввода регистрируется в форме с помощью директивы ngModel. В контексте родительской формы директиву можно использовать без привязки данных ([()]), вместо этого элемент управления регистрируется с использованием атрибута name ввода, а форма поддерживает синхронизацию данных.

<div class="card m-3">
    <h5 class="card-header text-center">Angular + Template-Driven Forms - Cross Field Validation Example</h5>
    <div class="card-body">
        <form #f="ngForm" (ngSubmit)="onSubmit(f)" [mustMatch]="['password', 'confirmPassword']" novalidate>
            <div class="row">
                <div class="col mb-3">
                    <label class="form-label">Password</label>
                    <input type="password" name="password" ngModel #password="ngModel" class="form-control" [ngClass]="{ 'is-invalid': f.submitted && password.invalid }" required minlength="6">
                    <div *ngIf="f.submitted && password.errors" class="invalid-feedback">
                        <div *ngIf="password.errors.required">Password is required</div>
                        <div *ngIf="password.errors.minlength">Password must be at least 6 characters</div>
                    </div>
                </div>
                <div class="col mb-3">
                    <label class="form-label">Confirm Password</label>
                    <input type="password" name="confirmPassword" ngModel #confirmPassword="ngModel" class="form-control" [ngClass]="{ 'is-invalid': f.submitted && confirmPassword.invalid }" required>
                    <div *ngIf="f.submitted && confirmPassword.errors" class="invalid-feedback">
                        <div *ngIf="confirmPassword.errors.required">Confirm Password is required</div>
                        <div *ngIf="confirmPassword.errors.mustMatch">Passwords must match</div>
                    </div>
                </div>
            </div>
            <div class="text-center">
                <button class="btn btn-primary me-1">Submit</button>
                <button class="btn btn-secondary" type="reset">Reset</button>
            </div>
        </form>
    </div>
</div>

Компонент приложения, который обрабатывает данные формы

Компонент мало что делает при использовании форм на основе шаблонов angular, поскольку поля формы и средства проверки настраиваются в шаблоне компонента.

Метод onSubmit() вызывается с переменной шаблона NgForm при отправке формы, он привязывается к элементу формы в шаблоне с использованием синтаксиса привязки событий Angular ((ngSubmit)="onSubmit(f)"). Если допустимо, отображается простое alert javascript со значениями, введенными в форму.

import { Component } from '@angular/core';
import { NgForm } from '@angular/forms';

@Component({ selector: 'app-root', templateUrl: 'app.component.html' })
export class AppComponent {
    onSubmit(f: NgForm) {
        // stop here if form is invalid
        if (f.invalid) {
            return;
        }

        alert('SUCCESS!! :-)\n\n' + JSON.stringify(f.value, null, 4));
    }
}

Пользовательский валидатор перекрестных полей MustMatch

Пользовательский валидатор MustMatch используется в примере для проверки совпадения обоих полей пароля. Однако его можно использовать для проверки любой пары полей (например, электронная почта и подтверждение электронной почты).

Он работает немного иначе, чем обычный валидатор, обычно валидатор ожидает параметр управления вводом, тогда как этот ожидает группу форм, потому что он проверяет два ввода вместо одного.

Кроме того, вместо того, чтобы возвращать ошибку, которая будет прикреплена к родительской форме group, валидатор вызывает matchControl.setErrors(), чтобы прикрепить ошибку к полю подтверждения пароля. Мы подумали, что это имеет больше смысла, потому что ошибка проверки отображается под полем confirmPassword в шаблоне.

import { AbstractControl } from '@angular/forms';

// custom validator to check that two fields match
export function MustMatch(controlName: string, matchingControlName: string) {
    return (group: AbstractControl) => {
        const control = group.get(controlName);
        const matchingControl = group.get(matchingControlName);

        if (!control || !matchingControl) {
            return null;
        }

        // return if another validator has already found an error on the matchingControl
        if (matchingControl.errors && !matchingControl.errors.mustMatch) {
            return null;
        }

        // set error on matchingControl if validation fails
        if (control.value !== matchingControl.value) {
            matchingControl.setErrors({ mustMatch: true });
        } else {
            matchingControl.setErrors(null);
        }
        return null;
    }
}

Пользовательская директива валидатора mustMatch

Пользовательская директива [mustMatch] является оболочкой пользовательского валидатора MustMatch, чтобы мы могли прикрепить его к форме. Пользовательская директива валидатора требуется при использовании форм на основе шаблонов, потому что у нас нет прямого доступа к FormGroup, как в реактивных формах.

Директива реализует интерфейс Validator и регистрируется у провайдера NG_VALIDATORS, чтобы сообщить angular, что это пользовательская директива валидатора.

Он принимает массив с именами двух элементов управления формы, которые должны совпадать, чтобы проверка формы прошла успешно, например. [mustMatch]="['field1', 'field2']" проверит, что поля field1 и field2 содержат одно и то же значение, в противном случае для поля field2 будет установлена ошибка проверки. Вы можете увидеть его использование в теге формы шаблона приложения выше.

import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, ValidationErrors, FormGroup } from '@angular/forms';

import { MustMatch } from './must-match.validator';

@Directive({
    selector: '[mustMatch]',
    providers: [{ provide: NG_VALIDATORS, useExisting: MustMatchDirective, multi: true }]
})
export class MustMatchDirective implements Validator {
    @Input('mustMatch') mustMatch: string[] = [];

    validate(formGroup: FormGroup): ValidationErrors | null {
        return MustMatch(this.mustMatch[0], this.mustMatch[1])(formGroup);
    }
}
#Angular
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу