0

I have been working on the implementation of model driven form for an application with many nested components.

It is an snippet of my current template

<div [formGroup]="formGroup">
  <mycomponent1 [formParam]="getForm('myForm1')"></mycomponent1>
  <mycomponent2 [formParam]="getForm('myForm2')"></mycomponent1>
  <mycomponent3 [formParam]="getForm('myForm3')"></mycomponent1>
</div>

.ts file snippet

ngOnInit() {
 this.formGroup= this.fb.group({
   myForm1 = this.fb.group({...}),
   myForm2 = this.fb.group({...}),
   myForm3 = this.fb.group({...})
 });
}

getForm(formName: string) {
  return <FormGroup>this.formGroup.get(formName);
}

My question is: does anyone know some other approach in order to implement a model driven form to nested components without the dependency to define an @Input form group parameter to the children components?

I mean, how to avoid to do this for every nested component?

@Input() formParam: FormGroup;

Why I'm asking that, because I have more nested components and I'm forced to define a formgroup as @Input in the rest of nested components which is very heavy work.

Cheers.

Daniel C.
  • 5,418
  • 3
  • 23
  • 26
  • 1
    Check out this video: https://www.youtube.com/watch?v=CD_t3m2WMM8 Kara covers nested form options there. – DeborahK Jan 11 '18 at 01:13
  • This mostly depends on what you're trying to achieve. There's no better way to pass it because it should be passed through input any way. But nested comps may be responsible for creating groups instead of receiving them from a parent. – Estus Flask Jan 11 '18 at 01:21
  • @DeborahK thank you so much, I just found concepts that I was ignoring, I'll try them and post my solution. Cheers – Daniel C. Jan 11 '18 at 02:18
  • 1
    Maybe: https://stackoverflow.com/questions/45696761/create-a-reusable-formgroup/46025197#46025197? – Lazar Ljubenović Jan 11 '18 at 22:49

1 Answers1

1

After many hours of testing and research I finally found a solution that fit to my requirements. Here it is:

  1. I totally remove every @Input() form: FromGroup from children components.

  2. My entire tree of form groups is created form the parent component.

  3. I can inject the individual form group to nested components using a viewProvider injection.

It is my Parent template

<div [formGroup]="form">
  <div [formGroup]="form.get('myForm1')"> <mycomponent1></mycomponent1> </div>
  <div [formGroup]="form.get('myForm2')"> <mycomponent2></mycomponent1> </div>
  <div [formGroup]="form.get('myForm3')"> <mycomponent3></mycomponent1> </div>
</div>

Parent template .ts file

ngOnInit() {
 this.formGroup= this.fb.group({
   myForm1 = this.fb.group({...}),
   myForm2 = this.fb.group({...}),
   myForm3 = this.fb.group({...})
 });
}

Child component where view provider is defined

@Component({
  selector: 'mycomponent1',
  templateUrl: './mycomponent1.html',
  viewProviders: [
    {
      provide: ControlContainer,
      useExisting: FormGroupDirective
    }
  ]
})

Here is where the form group directive is injected, so that I can access the form group created from parent component without use @Input() form: FormGroup

export class MyComponent1 {
   constructor(public parent: FormGroupDirective) {}
}

In child template I can access the form using parent.form

<div>
  <input formControlName="childControl1"></input>
  <input formControlName="childControl2"></input>
  <button[disabled]="parent.form.invalid" >Submit</button>
</div>
Daniel C.
  • 5,418
  • 3
  • 23
  • 26