Q: How to use Angular 2 template form with 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.

Leave a Comment

techhipbettruvabetnorabahisbahis forumueduseduseduseduseduedueduedueduedus