Реактивные формы в Angular
Формы являются неотъемлемой частью любого веб-приложения. Они используются повсеместно: от входа пользователя до регистрации или оформления заказа. Angular предоставляет мощный инструмент под названием реактивные формы, которые позволяют создавать сложные формы с использованием потоков событий RxJS.
Ключевые потоки каждого элемента управления формой
Каждый элемент управления (FormControl, FormGroup и FormArray) имеет два ключевых потока:
valueChanges: поток, который генерирует событие при каждом изменении значения.statusChanges: поток, который генерирует событие при любом изменении статуса проверки валидности («VALID», «INVALID», «PENDING» или «DISABLED»).
Пример использования этих потоков:
const emailControl = new FormControl('');
emailControl.valueChanges.subscribe(value => {
console.log('Новый e-mail:', value);
});
emailControl.statusChanges.subscribe(status => {
console.log('Статус:', status);
});
Пример живой проверки доступности имени пользователя
Один из самых распространенных сценариев использования реактивных форм — это проверка доступности имени пользователя во время ввода пользователем текста. Для реализации такой функциональности можно использовать операторы RxJS, такие как debounceTime, distinctUntilChanged и switchMap. Вот пример кода:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms';
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-register',
templateUrl: './register.component.html'
})
export class RegisterComponent implements OnInit, OnDestroy {
registerForm: FormGroup;
private ngUnsubscribe$ = new Subject<void>();
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.registerForm = this.fb.group({
username: ['', [
Validators.required,
Validators.minLength(3)
]]
});
this.registerForm.get('username').valueChanges.pipe(
debounceTime(500),
distinctUntilChanged(),
switchMap(username => this.checkAvailability(username))
).pipe(takeUntil(this.ngUnsubscribe$)).subscribe(result => {
console.log(`Доступность имени ${result}`);
});
}
ngOnDestroy(): void {
this.ngUnsubscribe$.next();
this.ngUnsubscribe$.complete();
}
}