I have one custom control component <some-input>
that i wrapped to <ext-some-input>
. SomeInput is encapsulated, has own API and supports reactive forms. ExtSomeInput is created as high-level wrapper over SomeInput.
I have following html:
<form [formGroup]="form"> <ext-some-input formControlName="name"> </form>
and ExtSomeInput's html:
<some-input formControlName="_???_"></some-input>
The question is how to forward formControlName to inner SomeInput component? I need to tie the form and inner formControl up. Is this possible?
EDITED:
I've created stackblitz project with this issue: here
You can also create your own custom components (or directives) that can be bound to form controls—if they implement ControlValueAccessor interface. Angular has built-in ControlValueAccessor implementations for <input> , <textarea> , etc, but not for <div> .
This means that: if we are using template driven forms, we will be able to plug the custom component to the form simply by using ngModel. and in the case of reactive forms, we will be able to add the custom component to the form using formControlName (or formControl )
[formControl] assigns a reference to the FormControl instance you created to the FormControlDirective . formControlName assigns a string for the forms module to look up the control by name.
Without a parent FormGroup, [formControl]="name" worked earlier because that directive can stand alone, that is, it works without being in a FormGroup. With a parent FormGroup, the name input needs the syntax formControlName=name in order to be associated with the correct FormControl in the class.
Your inner component can take @Input
controlName
but it won't work out of the box:
Error: formControlName must be used with a parent formGroup directive.
In order to tie your control with parent FormGroup you can define viewProvider
as follows:
import { Component, Input, OnInit} from '@angular/core'; ... import { ControlContainer, FormGroupDirective } from '@angular/forms'; @Component({ ... viewProviders: [ { provide: ControlContainer, useExisting: FormGroupDirective } ] }) export class DateWrapperComponent implements OnInit { @Input() controlName: string; }
Forked Stackblitz
In case you don't know which exactly directive is provided as a ControlContainer
(FormGroupDirective
, FormGroupName
or FormArrayName
) you can use more generic approach:
viewProviders: [ { provide: ControlContainer, useFactory: (container: ControlContainer) => container, deps: [[new SkipSelf(), ControlContainer]] } ]
Demo
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