Угловые валидаторы с условной проверкой в реактивных формах
Форма является неотъемлемой частью создания надежного и масштабируемого приложения Angular. Проверка формы заявки перед обращением к серверу повышает безопасность и производительность.
В этом посте я покажу вам, как использовать валидаторы в угловых реактивных формах; мы также использовали бы валидаторы для реализации условные проверки в реактивных формах.
Ниже в основном то, что вы узнаете в конце этого урока:
- Как создавать базовые формы Angular
- Как использовать валидаторы Angular с реактивными формами Angular
- Как реализовать условные проверки на основе определенных значений в форме.
Без лишних слов, давайте начнем!
Создание нового приложения Angular
Для начала нам нужно создать новое приложение Angular с помощью мощного Angular cli — убедитесь, что оно настроено локально.
Чтобы создать новый проект, просто введите следующую команду
ng new angular-reactive-validation
И это все! Angular-cli автоматически загрузит проект в папку с именем angular-reactive-validation
.
Создание угловой реактивной формы
Мы будем использовать существующие app.component.ts
файл для логики нашего компонента; не стесняйтесь использовать везде, где вы считаете нужным в своем приложении.
Создание группы форм
Существуют разные способы создания реактивной формы. Мой предпочтительный подход заключается в использовании FormGroup
рядом с FormBuilder
. Идея остается той же, даже если вы решите использовать FormControl
или любой другой подход — многие пути к рынку вы знаете.
Прежде всего, давайте импортируем FormBuilder
, FormGroup
, Validators
будем использовать в ближайшее время, а затем создадим два поля для работы с нашей формой:
...
import {FormGroup, FormBuilder, Validators} from '@angular/forms';
form: FormGroup;
formSubmitted = false;
-
form
переменная будет содержать форму, которую мы скоро создадим -
formSubmitted
содержит статус нашей формы: была ли она отправлена или нет, по умолчанию false.
Следующий!
Мы внедряем FormBuilder в конструктор класса.
constructor(private formBuilder: FormBuilder) {}
Давайте построим нашу форму внутри метода с именем buildForm
:
buildForm() {
this.form = this.formBuilder.group({
email: [null],
username: [null],
userCategory: ['employee'],
institution: [null],
company: [null],
salary: [null],
});
}
Это все, что нам нужно добавить к нашему app.component.ts
файл на данный момент, но давайте кратко объясним, что мы сделали:
Мы использовали FormBuilder
вводится в конструктор для построения формы и присваивается значение this.form
поле, которое мы объявили в классе ранее.
Отправить
Когда наша форма отправлена, мы создаем onSubmit
способ справиться с этим:
onSubmit(event) {
event.preventDefault();
this.formSubmitted = true;
if (this.form.valid) {
console.log(this.form.value);
}
}
Здесь ничего особенного не происходит. Когда форма отправлена, мы устанавливаем this.formSubmitted
поле в истину; затем мы проверяем, действительна ли форма, прежде чем записывать ее в консоль — на самом деле вы обрабатываете форму и отправляете ее на сервер.
Шаблон компонента
Откройте app.component.html и добавьте следующий код:
<h3 class="text-center">User Details</h3>
<hr>
<form [formGroup]="form" (ngSubmit)="onSubmit($event)">
<div>
<label for="email">Email</label>
<input type="email" id="email" formControlName="email" placeholder="Enter email"/>
</div>
<div>
<label for="username">Username</label>
<input type="text" id="username" formControlName="username" placeholder="Username"/>
</div>
<div>
<input type="radio" formControlName="userCategory" id="userCategory2" value="employee"/> Employee
<input type="radio" formControlName="userCategory" id="userCategory1" value="student"/> Student
</div>
<div>
<label for="institution">Institution </label>
<input type="text" id="institution" formControlName="institution" placeholder="Enter institution"/>
</div>
<div>
<label for="company">Company</label>
<input type="text" id="company" formControlName="company" placeholder="Enter company"/>
</div>
<div>
<label for="salary">Salary</label>
<input type="text" id="salary" formControlName="salary" placeholder="Enter salary"/>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Мы добавили formGroup
директива для тега формы, а также formControlName
для каждого ввода формы. Мы также связали наши onSubmit
метод формы ngSubmit
мероприятие. Это все, что нужно для начала реализации реактивной проверки формы.
Вернемся к нашему классу компонентов!
Добавление проверки
Мы будем использовать встроенные валидаторы Angular для проверки формы — тот, который мы импортировали ранее:
buildForm() {
this.form = this.formBuilder.group({
email: [null, [Validators.required, Validators.email]],
username: [null, [Validators.required]],
userCategory: ['employee'],
institution: [null, [Validators.required]],
company: [null, [Validators.required]],
salary: [null, [Validators.required]],
});
}
Как видите, все поля формы обязательны для заполнения, кроме userCategory
который, конечно же, является переключателем со значением по умолчанию работник.
Давайте позвоним buildForm
метод в нашем классе ngOnInit
метод:
ngOnInit() {
this.buildForm();
}
Обновление шаблона компонента
После добавления проверки в поля нашей реактивной формы нам нужно внести некоторые изменения в шаблон компонента. Добавлять [ngClass]="{'form-submitted': formSubmitted}"
к каждому входу формы шаблона. Что-то вроде этого:
<input type="text" id="username" formControlName="username" [ngClass]="{'form-submitted': formSubmitted}" placeholder="Username"/>
С этим ngClass
мы просто попросили Angular добавить класс form-submitted
на вход всякий раз, когда formSubmitted
поле в нашем классе истинно. Буквально добавить класс form-submitted
в поле ввода всякий раз, когда форма была отправлена. Мы будем использовать класс для стилизации в следующем разделе.
Использование CSS для выделения недопустимых полей формы
На данном этапе мы все еще не можем увидеть эффект только что реализованных проверок. Нам нужно написать немного css.
При работе с реактивными формами Angular автоматически добавляет некоторые классы в каждое поле формы. Каждый из этих классов соответствует состоянию полей при отображении формы и при взаимодействии с ними пользователя. Таким образом, эти классы:
- действительный
- недействительный
- тронутый
- нетронутого
- нетронутый
- в ожидании
- грязный
Вы можете узнать больше о каждом из этих классов здесь: классы угловых форм
Давайте откроем app.component.css
и добавьте следующий css:
.ng-valid.ng-dirty:not(form) {
border: solid 2px lightgreen;
}
.ng-invalid.ng-dirty:not(form), .ng-invalid:not(form).form-submitted {
border: solid 2px lightcoral;
}
Здесь мы делаем две вещи:
- Мы выделяем границу ввода формы светло-зеленым цветом, но только тогда, когда пользователь ввел что-то в поле и является допустимым.
- Мы выделяем границу ввода формы светло-коралловым цветом, но только тогда, когда пользователь ввел что-то в поле и является недопустимым вводом. Мы также следим за тем, чтобы все недействительные поля выделялись одним цветом после отправки формы.
Если мы добавим некоторые стили начальной загрузки, форма после отправки без значений должна выглядеть примерно так:
И это все. Вы узнали, как реализовать проверки в реактивной форме Angular, используя валидаторы.
Пора переходить к условная проверка в реактивных формах Angular — наша следующая тема дня.
Условная проверка в реактивных формах
Пока все хорошо, наша форма была проверена, но, скажем так, это не тот результат, которого мы хотим. В настоящее время форма недействительна, пока пользователь не заполнит все обязательные поля.
Мы хотим, чтобы наша форма была действительна для следующих условий:
- Когда категория пользователя является работникполе
institution
не требуется: должно быть необязательным. - Когда категория пользователя является ученикполя
company and salary
не должно требоваться; они должны быть необязательными.
Это означает, что у нас есть изменения, которые нужно внести для категория пользователя когда пользователь переключается между двумя значениями (сотрудник или студент).
Приступим к делу!
Настройка проверки для категории пользователя
Создадим новый метод setUserCategoryValidators
со следующим кодом:
setUserCategoryValidators() {
const institutionControl = this.form.get('institution');
const companyControl = this.form.get('company');
const salaryControl = this.form.get('salary');
this.form.get('userCategory').valueChanges
.subscribe(userCategory => {
if (userCategory === 'student') {
institutionControl.setValidators([Validators.required]);
companyControl.setValidators(null);
salaryControl.setValidators(null);
}
if (userCategory === 'employee') {
institutionControl.setValidators(null);
companyControl.setValidators([Validators.required]);
salaryControl.setValidators([Validators.required]);
}
institutionControl.updateValueAndValidity();
companyControl.updateValueAndValidity();
salaryControl.updateValueAndValidity();
});
}
Давайте обсудим, что здесь происходит:
- Мы начинаем с получения элементов управления соответствующими полями, которые нам нужно проверить, используя наш
this.form
и присвоил их локальным переменным — для повторного использования. - Затем мы используем наш
this.form
еще раз, чтобы получить доступ кuserCategory
формировать элемент управления и подписываться на изменения его значения. - Внутри нашего обратного вызова подписки, в первом
if statement
мы проверяем, является ли значение ученик. Если это так, мы используем встроенный элемент управления формой Angular.setValidators
способ добавления проверки кinstitution
поле. Мы также используем тот же метод для удаления проверки изcompany
а такжеsalary
полей, установив для них значение null. Этот шаблон также используется для второгоif statement
что в значительной степени интуитивно понятно. - Наконец, мы используем элемент управления формы Angular
updateValueAndValidity
способ обновления полей. Здесь важно отметить, что вызовsetValidators
метод без вызоваupdateValueAndValidity
метод будет составлять никаких изменений в форме. То есть никакие изменения не будут внесены в форму и ее проверки.updateValueAndValidity
на самом деле это метод, который информирует Angular о внесении новых изменений в элемент управления формой. Следовательно, всегда убедитесь, что он вызывается после вызова setValidators для элементов управления.
Вызов setUserCategoryValidators
метод в ngOnInit
теперь должно выглядеть так:
ngOnInit() {
this.buildForm();
this.setUserCategoryValidators();
}
Обновление валидации метода buildForm
Последнее, что нужно сделать, это обновить проверки формы в методе buildForm:
buildForm() {
this.form = this.formBuilder.group({
email: [null, [Validators.required]],
username: [null, [Validators.required]],
userCategory: ['employee'],
institution: [null],
company: [null, [Validators.required]],
salary: [null, [Validators.required]],
});
}
Как видно, категория пользователя установлена на employee
по умолчанию. Затем мы можем удалить проверку для поля учреждения. Наш новый setUserCategoryValidators
вызовет соответствующую проверку для учреждения, если пользователь выберет вариант студента для категории пользователя, и наоборот.
Собрав все вместе, когда пользователь выбрал студента в качестве категории пользователя и нажал кнопку «Отправить», выделенные поля теперь должны выглядеть так:
На картинке выше мы видим, что зарплата а также Компания поля не выделены, но учреждение выделен вместе с другими обязательными полями. зарплата а также Компания поля теперь являются необязательными.
Как показано выше, также, когда пользователь переключился на employee
, зарплата а также Компания поля становятся выделенными, а учреждение поле становится необязательным и поэтому не выделяется.
Вывод
В этом уроке мы можем охватить следующее:
- Как создать базовую форму Angular, используя реактивный подход
- Как использовать встроенные валидаторы Angular с реактивными формами
- Как использовать css, чтобы выделить наши недействительные поля формы
- Как использовать элементы управления формы Angular
setValidators
а такжеupdateValueAndValidity
методы для установки условных проверок в полях формы.
Если вы хотите увидеть полный исходный код, посетите Репозиторий Github
Я хотел бы услышать ваши исправления, предложения или отзывы в разделе комментариев. Спасибо за ваше время!