Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forwarding formControlName to inner component in Angular

Tags:

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

like image 282
skorenb Avatar asked Oct 19 '18 13:10

skorenb


People also ask

Can we give formControlName to div?

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> .

Can we use formControlName with ngModel?

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 )

What is the difference between FormControl and formControlName?

[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.

Can we use formControlName without FormGroup?

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.


1 Answers

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

like image 193
yurzui Avatar answered Sep 22 '22 14:09

yurzui