I need to be able to use the formControlName
directive for my custom component.
I've been reading through the multiple SO questions about implementing ControlValueAccessor
for a child component, and it all seems very fragile.
A lot of the examples are transforming <div>
or <span>
elements into form elements, and so it makes sense to implement all the functionality expected by ControlValueAccessor
.
However, my component is just using the native <input>
element. I'm creating a separate component because I want to use some icons with the input, and I obviously don't want to copy/paste the icon css everywhere.
I've come across the DefaultValueAccessor
class which seems to be what's used by angular for all the native input elements. Can I leverage this behavior somehow for my custom component as well?
I just don't want to replicate this functionality. It could be difficult to maintain it over the long term with regards to bugs and various browser behavior. I would rather just use the functionality that's already associated with the native inputs.
Here's the code snippet of <jg-search>
(my custom component):
<div>
<svg>
<!-- some content -->
</svg>
<label for="search">Search</label>
<input id="search" type="text"></input>
<svg>
<!-- some content -->
</svg>
</div>
I want to be able to just call it this way in a form: <jg-search formControlName="keyword">
.
This is possible by implementing ControlValueAccessor
in the SearchComponent. But since I'm just using the native <input type="text">
, I don't want to reimplement the functionality already defined in DefaultValueAccessor
.
ControlValueAccessor provides the ability to use FormControl with any component that implements this interface. This gives a lot of development flexibility and is a useful feature in Angular Forms . There are several ways with some boilerplate to control decoration and usage.
The registerOnChange method should be called whenever the value changes - in our case, when a star is clicked on. The registerOnTouched method should be called whenever our UI is interacted with - like a blur event.
Control Value Accessor is an interface that provides us the power to leverage the Angular forms API and create a communication between Angular Form API and the DOM element. It provides us many facilities in angular like we can create custom controls or custom component with the help of control value accessor interface.
One possible solution could be using ngDefaultControl
attribute on your custom component:
<div [formGroup]="form">
<jg-search formControlName="x" ngDefaultControl></jg-search>
^^^^^^^^^^^^^^^^
</div>
now all you need to do is to link your input
element with existing FormControl as follows:
@Component({
selector: 'jg-search',
template: `
<input [formControl]="ngControl.control">
`
})
export class MyInput {
constructor(public ngControl: NgControl) {}
}
For more detals see Ng-run Example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With