Let us assume, we have a custom Angular component that acts as a form control and we want to subscribe to “onTouch” Event on it.
PS: Control Value Accessor interface gives us the power to leverage the Angular forms API, and create a connection between it and the DOM element.
This interface requires the implementation of several methods, including registerOnChange
and registerOnTouched
.
Here’s how we can implement the registerOnTouched
method in our custom component :
import { Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-custom-input',
template: `
<input [(ngModel)]="value" />
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true,
},
],
})
export class CustomInputComponent implements ControlValueAccessor {
value: any;
private onTouch: () => void = () => {};
writeValue(value: any): void {
this.value = value;
}
registerOnChange(fn: (value: any) => void): void {
// Implement the logic when the value changes
}
registerOnTouched(fn: () => void): void {
this.onTouch = fn;
}
setDisabledState?(isDisabled: boolean): void {
// Implement logic to set the component as disabled if needed
}
}
In this example:
- The
registerOnTouched
method is implemented to store the function passed by Angular forms. This function (onTouch
) will be called when the control is “touched,” which means the user has interacted with the control in a way that indicates they have focused on it and then moved away (e.g., clicking inside and then clicking outside). - The
onTouch
function is then called in the appropriate places in our component where we determine that the control has been touched. Typically, this might happen when the user interacts with the UI element we are wrapping (like an input field). For example, we might callthis.onTouch()
in theblur
event handler of the input.
Here’s an example of how we might handle the blur
event:
import { Component } from '@angular/core';
@Component({
selector: 'app-custom-input',
template: `
<input [(ngModel)]="value" (blur)="onInputBlur()" />
`,
})
export class CustomInputComponent implements ControlValueAccessor {
onInputBlur() {
// Logic to determine that the input has been touched
this.onTouch
}
}