Angular предлагает расширенный набор встроенных элементов управления формами для создания динамических и интерактивных форм. Однако бывают случаи, когда эти элементы управления не соответствуют определенным требованиям или предпочтениям дизайна. Вот где пригодится возможность создавать собственные элементы управления формой в Angular 🙌.
Пользовательский элемент управления формой
Чтобы создать собственный элемент управления формой в Angular, вы можете выполнить следующие шаги 👇
1. Создайте компонент для пользовательского элемента управления формы.
$ ng generate component custom-input
2. В файле TypeScript компонента реализуйте интерфейс ControlValueAccessor
.
import { Component } from '@angular/core' import { ControlValueAccessor } from '@angular/forms' @Component({ selector: 'app-custom-input', templateUrl: './custom-input.component.html', styleUrls: ['./custom-input.component.css'] }) export class CustomInputComponent implements ControlValueAccessor {}
3. Предоставьте токен NG_VALUE_ACCESSOR
и настройте его на использование функции forwardRef
для ссылки на ваш пользовательский элемент управления.
import { Component, forwardRef } from '@angular/core' import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' @Component({ selector: 'app-custom-input', templateUrl: './custom-input.component.html', styleUrls: ['./custom-input.component.css'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CustomInputComponent), multi: true } ] }) export class CustomInputComponent implements ControlValueAccessor {}
4. Реализуйте методы ControlValueAccessor
.
writeValue(obj: any): void
— обновляет значение элемента управления формы на основе предоставленного параметра value.registerOnChange(fn: any): void
— регистрирует функцию обратного вызова, которая будет вызываться при изменении значения элемента управления формы.registerOnTouched(fn: any): void
— регистрирует функцию обратного вызова, которая будет вызываться при касании элемента управления формы.setDisabledState(isDisabled: boolean): void
— устанавливает отключенное состояние элемента управления формы на основе предоставленного логического параметра.
@Component(...) export class CustomInputComponent implements ControlValueAccessor { value: string; disabled = false; onChange: any = (value: any) => {}; onTouched: any = () => {}; writeValue(obj: any): void { this.value = obj; } registerOnChange(fn: any): void { this.onChange = fn; } registerOnTouched(fn: any): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } }
5. Создайте шаблон для пользовательского элемента управления формы:
- В шаблон добавьте селектор для вашего пользовательского компонента управления.
- Привяжите элемент управления к форме с помощью директив
ngModel
,formControl
илиformControlName
, как и для любого другого элемента управления формы.
<input type="text" [(ngModel)]="value" [disabled]="disabled" (input)="onChange(value)" (blur)="onTouched()" />
6. Используйте настраиваемый элемент управления формы:
- Создайте форму, в которой вы хотите использовать настраиваемый элемент управления формы.
@Component(...) export class AppComponent { form = new FormGroup({ name: new FormControl(''), }); }
- Включите настраиваемый компонент управления в форму в шаблоне.
<form [formGroup]="form"> <app-custom-input formControlName="name"></app-custom-input> </form>
Пользовательские валидаторы
Вот пример того, как добавить валидаторы в компонент пользовательского элемента управления 👇
1. В файле TypeScript компонента реализуйте интерфейс Validator
.
import { Component, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, Validator } from '@angular/forms'; @Component(...) export class CustomInputComponent implements ControlValueAccessor, Validator {}
2. Укажите токен NG_VALIDATORS
и настройте его на использование функции forwardRef
для ссылки на ваш пользовательский элемент управления.
import { Component, forwardRef } from '@angular/core' import { ControlValueAccessor, NG_VALUE_ACCESSOR, Validator, NG_VALIDATORS } from '@angular/forms' @Component({ selector: 'app-custom-input', templateUrl: './custom-input.component.html', styleUrls: ['./custom-input.component.css'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CustomInputComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => CustomInputComponent), multi: true } ] }) export class CustomInputComponent implements ControlValueAccessor, Validator {}
3. Реализуйте метод validate
в пользовательском компоненте управления.
Метод validate
— это то место, где вы можете выполнить собственную логику проверки. Возвращая объект ValidationErrors
с определенными ключами и значениями, вы можете предоставить настраиваемые сообщения об ошибках проверки для элемента управления формы. Если ошибок проверки нет, возврат null
означает, что элемент управления считается действительным.
validate(control: AbstractControl): ValidationErrors | null { // Perform validation logic here if (!control.value || control.value === '') { return { required: true }; } return null; }
4. Обновите элемент управления формы в шаблоне родительского компонента, чтобы включить валидатор:
<form [formGroup]="form"> <app-custom-input formControlName="name"></app-custom-input> <div *ngIf="form.controls.name.invalid && form.controls.name.touched"> <span *ngIf="form.controls.name.errors?.required" >This field is required</span > </div> </form>
Заключение
В заключение, создание настраиваемых элементов управления формами в Angular позволяет разработчикам создавать формы, персонализированные в соответствии с их конкретными потребностями и вариантами дизайна. Поняв, как работает модуль Angular Reactive Forms, и используя его компонентный подход, вы теперь можете создавать собственные элементы управления, которые будут одновременно функциональными и визуально привлекательными для ваших приложений.
Подведение итогов
Я надеюсь, что благодаря этой статье вы теперь знаете, как создавать собственные элементы управления формой в Angular. Если вы хотите увидеть весь пример, вы можете сделать это здесь, на StackBlitz ⚡️.
Если вам понравилось это читать, пожалуйста, хлопните в ладоши 👏 . Не стесняйтесь подписываться на меня и оставлять комментарии с вашими отзывами 👇.