Is it not possible to have form input elements within an ng-content and have that "connect" to the ngForm instance of the parent component?
Take this basic template for a parent component:
<form (ngSubmit)="onSubmit(editForm)" #editForm="ngForm" novalidate> <ng-content></ng-content> <button type="submit">Submit</button> </form>
Then inside the child component, which is put inside "ng-content", something like this:
<input type="text" [(ngModel)]="user.firstName" #firstName="ngModel" name="firstName" required minlength="2">
On submit of the parent form, the child controls are not available, which also means that dirty/validation of whatever is in the child component is not reflected on the parent form.
What is missing here?
If you want to style the projected content within <ng-content>, you can do so using :host and ::ng-deep to apply styling to all nested elements within the <contact> component.
Angular provides two different approaches to handling user input through forms: reactive and template-driven.
The ng-content is used when we want to insert the content dynamically inside the component that helps to increase component reusability. Using ng-content we can pass content inside the component selector and when angular parses that content that appears at the place of ng-content.
There is a good chance that you have come up with another solution at this point but I just figured out a way to do this. Hopefully it will help you or someone else.
import { NgModel } from '@angular/forms'; import { Component, ContentChildren, ViewChild, QueryList, AfterViewInit } from '@angular/core'; @Component({ selector: 'my-custom-form', template: ` <form (ngSubmit)="onSubmit(editForm)" #editForm="ngForm" novalidate> <ng-content></ng-content> <button type="submit">Submit</button> </form> `, }) export class MyCustomFormComponent implements AfterViewInit { @ContentChildren(NgModel) public models: QueryList<NgModel>; @ViewChild(NgForm) public form: NgForm; public ngAfterViewInit(): void { let ngContentModels = this.models.toArray(); ngContentModels.forEach((model) => { this.form.addControl(model); }); } public onSubmit(editForm: any): void { console.log(editForm); } }
Then you can use it in your template like this:
<my-custom-form> <input name="projectedInput" ngModel> </my-custom-form>
When you submit the form, you will see that the projectedInput form control is added to the NgForm.
Note: I only tried adding the projected inputs from the AfterViewInit lifecycle hook. It may work earlier, I'm not sure. There also may be some issues with doing this that I'm not aware of. YMMV.
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