CustomControlComponent:
import { Component, forwardRef, OnDestroy, OnInit } from '@angular/core';
import {
ControlValueAccessor,
FormBuilder,
FormControl,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
ValidationErrors,
Validator
} from '@angular/forms';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-custom-control',
templateUrl: './custom-control.component.html',
styleUrls: ['./custom-control.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomControlComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => CustomControlComponent),
multi: true,
}
],
})
export class CustomControlComponent
implements OnInit, OnDestroy, ControlValueAccessor, Validator {
control = this.fb.control(null);
private onTouched = () => {};
private readonly ngUnsubscribe$ = new Subject<void>();
constructor(
private fb: FormBuilder
) {}
ngOnInit() {}
ngOnDestroy() {
this.ngUnsubscribe$.next();
this.ngUnsubscribe$.complete();
}
registerOnChange(onChange: (value: string | null) => void) {
this.control.valueChanges
.pipe(
takeUntil(this.ngUnsubscribe$)
)
.subscribe(onChange);
}
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
writeValue(outsideValue: string | null) {
if (outsideValue) {
this.control.setValue(outsideValue, { emitEvent: false });
}
}
setDisabledState(disabled: boolean) {
if (disabled) {
this.control.disable();
} else {
this.control.enable();
}
}
validate(c: FormControl): ValidationErrors | null {
const value = this.control.value;
const error = value === 'e';
return error ? { customErr: 'customErr' } : null;
}
}
<div>component2 err: {{control?.errors | json}}</div>
<div>component2 val: {{control?.value | json}}</div>
<input [formControl]="control" class="text-control" />
AppComponent:
<div>component1 err: {{control?.errors | json}}</div>
<div>component1 val: {{control?.value | json}}</div>
<hr>
<app-custom-control [formControl]="control"></app-custom-control>
import { Component, VERSION } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
control = new FormControl(null, Validators.required);
}