I am currently trying out the custom form controls of angular. For this i am building a simple example component with a FormGroup with firstName and lastName. Everything works fine so far, but i've got a question. Maybe someone here has a hint for me. I'm binding my "externalControl" in the parent component with the following code:
form = new FormGroup({
name: new FormControl(null, Validators.required);
});
<div [formGroup]="form">
<name-input [formControl]="form.get('name')"></name-input>
</div>
As you can see my parent form has a required validator. So in my custom form control i want to check, whether my parent form has a given validator and if it is valid. Here i am struggling a little bit. I am currently using the build in angular function "validate()" to get the "externalControl" and bind it in my custom-form-control. This may be bad practice, but i did not find any other way to check whether my parent-form has validation errors.
The code of my custom form control:
@Component({
selector: 'name-input',
templateUrl: './name-input.component.html',
styleUrls: ['./name-input.component.scss'],
// changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: NameInputComponent
},
{
provide: NG_VALIDATORS,
multi: true,
useExisting: NameInputComponent
}
]
})
export class NameInputComponent implements ControlValueAccessor, Validator {
form: FormGroup;
externalControl: AbstractControl;
constructor() {
this.initForm();
}
/** `View -> model callback called when value changes` */
_onChange: (value: any) => void = () => {
}
/** `View -> model callback called when select has been touched` */
_onTouched = () => {
}
change(value: string): void {
this._onChange(value);
this._onTouched();
}
validate(ctrl: AbstractControl): any {
// TODO: Is this really okay?
this.externalControl = ctrl;
console.log(this.externalControl.errors);
}
/**
* @description
* Method of ControlValueAccessor -> Allows Angular to update the model (value). The valueChanged event should always be emitted
* if the current value is changing. This applies to changes from outside and from direct user interactions.
*/
writeValue(value: any): void {
if (value) {
this.form.setValue(value, {emitEvent: false});
}
}
/**
* @description
* Method of ControlValueAccessor -> Allows Angular to register a function to call when the model (value) changes.
* The forms api is passing us the function, which it wants us to call.
*/
registerOnChange(fn: (value: any) => void): void {
this._onChange = fn;
this.form.valueChanges.subscribe(fn);
}
/**
* @description
* Method of ControlValueAccessor -> Allows Angular to register a function to call when the input has been touched.
*/
registerOnTouched(fn: () => void): void {
this._onTouched = fn;
}
/**
* @description
* Method of ControlValueAccessor -> Allows Angular to disable the input.
*/
setDisabledState(isDisabled: boolean): void {
isDisabled ? this.form.disable() : this.form.enable();
}
private initForm(): void {
this.form = new FormGroup({
firstName: new FormControl(),
lastName: new FormControl()
});
}
}