One simple solution is to provide ControlContainer in viewProviders array of your child component like:
import { ControlContainer, NgForm } from '@angular/forms';
@Component({
...,
viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class ChildComponent {}
Stackblitz Example
Read also this article that explains why it’s working.
- Angular: Nested template driven form
Update
If you’re looking for nested model driven form then here is the similar approach:
@Component({
selector: 'my-form-child',
template: `<input formControlName="age">`,
viewProviders: [
{
provide: ControlContainer,
useExisting: FormGroupDirective
}
]
})
export class ChildComponent {
constructor(private parent: FormGroupDirective) {}
ngOnInit() {
this.parent.form.addControl('age', new FormControl('', Validators.required))
}
}
Ng-run Example
Update 2
If you don’t know exactly which type of ControlContainer wraps your custom component(for example your controls is inside FormArray directive) then just use common version:
import { SkipSelf } from '@angular/core';
import { ControlContainer} from '@angular/forms';
@Component({
...,
viewProviders: [{
provide: ControlContainer,
useFactory: (container: ControlContainer) => container,
deps: [[new SkipSelf(), ControlContainer]],
}]
})
export class ChildComponent {}
Ng-run Example