3

I want to create a reusable form component to be used like:

<my-form>
   <input [ngModel]="value" (ngModelChange)="onChange($event)"/>
</my-form>

The <my-form> component looks like:

<form>
  <ng-content></ng-content>
</form>

However the form in my-form component does not see elements injected with any hence form.valid/dirty etc does not update if elements in form change

This problem/issue has been asked a couple times here on stackoverflow, see https://stackoverflow.com/questions/40843307/q-how-to-use-angular-2-template-form-with-ng-content

The solution is to add elements manually to the form like:

 public ngAfterViewInit(): void {
    let ngContentModels = this.models.toArray();
    ngContentModels.forEach((model) => {
    this.form.addControl(model);
});

}

With this workarround, form correctly updates valid/dirty etc properties, however, every change on the injected element results in firing ngModelChange events twice. In my example, the method onChange($event) is called 2 times with every change

<input [ngModel]="value" (ngModelChange)="onChange($event)"/>

Do you know how to "fix" the manually adding elements workarround? Or is there any other way how to handle forms with <ng-content> injected elements?

Antoni
  • 41
  • 1
  • 5

1 Answers1

0

When you want your component (my-form) to be aware of the outer form, you should consider adding it as an input and passing it through:

@Input myForm: FormGroup;
<form [formGroup]="myForm">
  <ng-content></ng-content>
</form>
naeramarth7
  • 6,030
  • 1
  • 22
  • 26