Forwarding formControlName to inner component in Angular

て烟熏妆下的殇ゞ 提交于 2019-12-06 02:04:57

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

You can create a @Input in component ext-some-input

ext-some-input.ts

@Input 
formControlName

ext-some-input.html

<some-input [formControlName]="formControlName"></some-input>

I think that you're actually looking something a bit more complex than an input.

If you want to create a customized input you can create a class which is going to be a ControlValueAccessor (custom form control).

Please check the following article where it's really well explained:

https://alligator.io/angular/custom-form-control

I've run into a similar scenario where I did not want to pass formControlName to the wrapper component. My preferred way to solve this is to just reuse the formGroup passed from the parent form in the wrapper component. You can do this by injecting ControlContainer in the constructor of ExtSomeInput component:

ParentForm.component.html

<form [formGroup]="form">
  <ext-some-input controlName="name">
</form>

ExtSomeInput.component.ts

// pass the formControlName as string to wrapper
@Input public controlName: string;
public form: FormGroup;

constructor(public controlContainer: ControlContainer) {}

ngOnInit() {
  this.form = <FormGroup>this.controlContainer.control;
}

ExtSomeInput.component.html

// use ng-container to omit this from the DOM
<ng-container [formGroup]="form">
  // wrapper markup here
  <some-input [formControlName]="controlName"></some-input>
</ng-container>

Hey making a second answer here because we came up at work with a generic approach that we released as an open source library =).

You can find it here: https://github.com/cloudnc/ngx-sub-form

It should help you manage: - nested forms - forms with polymorphic data - better typings

Everything is explained into the readme and a complete example is provided into the /src folder. (lib is actually in projects/ngx-sub-form).

Live demo available here too: https://cloudnc.github.io/ngx-sub-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!