Daniella
Daniella

Reputation: 129

Getting form data from a dynamic component in Angular 4

I'm struggling a lot with Angular 4 (is pretty new to me)...

My problem:

I'm having a form and in this form the user can add some new fields (when he clicks on a btn) - and it can be any number of fields. For that to be possible, I generate a new component in the form component (at every click).

I have in ts:

 export class FormComponent {
    @ViewChild('container', {read: ViewContainerRef}) container:ViewContainerRef;

    // this fires on click of the use which wants to add some fields
    public addComponent() {
    @Component({templateUrl: './pathToHtml'})
    class TemplateComponent {}
    @NgModule({declarations: [TemplateComponent], imports: [CommonModule, FormsModule]})
        class TemplateModule {}

        const mod = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
        const factory = mod.componentFactories.find((comp) =>
            comp.componentType === TemplateComponent
        );
        const component = this.container.createComponent(factory);
        }
}

In html I have separate templates for each component - the FORM component and the TEMPLATE one.

Sample from the form:

<form action="" (ngSubmit)="save(configHeadersForm.form)" #configHeadersForm="ngForm">

 <input type="text" class="form-control" name="test" ngModel required/>
</form>

Sample from the template:

 <input type="text" name="test2" ngModel>

In the form class in save function (which fires on submit and should have the form data) if I print form.value (I put in the input fields 'asddffd'), I have:

 Object { "test": 'asddffd'}

So only the value from the FORM template, not also the one from the generated component (test2). Any ideas, pretty please?:)

Upvotes: 1

Views: 851

Answers (1)

penleychan
penleychan

Reputation: 5470

To get this to work the correct way you have to implement ControlValueAccessor, alternatively another work around while able to use template driven on your child components is to create a directive.

@Directive({
   selector: '[provide-parent-form]',
   providers: [
   {
      provide: ControlContainer,
      useFactory: function (form: NgForm) {
        return form;
      },
      deps: [NgForm]
   }
 ]
})
export class ProvideParentForm {}

Then on your component you would use the directive as follow (Needs to be at the root of your template before ngModel):

<div provide-parent-form>
   <input type="text" name="test2" ngModel>
</div>

Upvotes: 0

Related Questions