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 ⚡️.
Если вам понравилось это читать, пожалуйста, хлопните в ладоши 👏 . Не стесняйтесь подписываться на меня и оставлять комментарии с вашими отзывами 👇.