Я создал пользовательский компонент mat-checkbox и реализовал интерфейс ControlValueAccessor для связи с переданным formControl или ngModel.
Флажок обновляет назначенный formControl при изменении, однако моя проблема в том, что онКажется, не регистрирует функции валидатора ни на основе шаблонов, ни на реактивном способе.
Это мой компонент:
import {Component, Input, OnInit, Self, ViewEncapsulation} from '@angular/core';
import {ControlValueAccessor, NgControl} from '@angular/forms';
@Component({
selector: 'app-checkbox',
templateUrl: './checkbox.component.html',
styleUrls: ['./checkbox.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class CheckboxComponent implements OnInit, ControlValueAccessor {
@Input() id: string;
@Input('aria-label') ariaLabel: string;
@Input() label: string;
private isChecked = false;
private isDisabled = false;
onChange = (isChecked: boolean) => {};
onTouched = () => {};
constructor(@Self() public controlDir: NgControl) {
// providing component as ControlValueAccessor
controlDir.valueAccessor = this;
}
ngOnInit() {
// Initializing assigned FormControl and providing it's Validator
const control = this.controlDir.control;
control.setValidators(control.validator);
control.updateValueAndValidity();
}
/**
* ControlValueAccessor interface (https://angular.io/api/forms/ControlValueAccessor)
* Registers a callback function that is called when the control's value changes in the UI.
* @param fn callback function
*/
registerOnChange(fn: (value: boolean) => void): void {
this.onChange = fn;
}
/**
* Input change callback that passes the changed string to this.onChange method
*/
valueChanged(value: boolean) {
this.onChange(value);
}
/**
* ControlValueAccessor interface
* Registers a callback function is called by the forms API on initialization to update the form model on blur.
* @param fn callback function
*/
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
/**
* (optional) - ControlValueAccessor interface
* Function that is called by the forms API when the control status changes to or from 'DISABLED'. Depending on the status, it enables or disables the appropriate DOM element.
* @param isDisabled control state
*/
setDisabledState(isDisabled: boolean): void {
this.isDisabled = isDisabled;
}
/**
* ControlValueAccessor interface
* Writes a new value to the element.
* @param value new control value
*/
writeValue(value: boolean): void {
if (value) {
this.isChecked = value;
}
}
}
А это мой шаблон:
<mat-checkbox color="primary" [checked]="isChecked" [disabled]="isDisabled" [id]="id" [attr.aria-label]="ariaLabel" (change)="valueChanged($event.checked)" (blur)="onTouched()">
{{label}}
</mat-checkbox>
Вот как я называю свой компонент управляемым шаблоном способом:
<form class="row border-bottom" #checkboxForm2="ngForm">
<div class="col-12 col-md-4 my-1">
checkboxForm2.value: <br>
{{checkboxForm2.value | json}} <br>
checkboxForm2.valid: {{checkboxForm2.valid}}
</div>
<div class="col-12 col-md-8 my-3">
<app-checkbox [ngModel]="false" name="checkbox3" label="REQUIRED" required></app-checkbox>
</div>
</form>
checkboxForm2.valid
всегда остается верным.Как я могу заставить работать требуемый валидатор?