Search code examples
angularangular2-directivesangular2-components

angular 2: Using dynamic components pass all inputs value to other components while click on submit button


I have created multiple dynamic components with some inputs fields. Now, I want to send all the inputs values into other components while click on Submit button.

Scenario is,

  • Click Add button at 5 times. Now, it will create 5 rows with input fields
  • Then, click on submit button, it will alert all input values. Here, the problem I tried to use @Input/@Output but I couldn't make it to run.

Plunker

    import { Component, ViewContainerRef, ElementRef, ComponentRef, ComponentResolver, ViewChild } from '@angular/core';

@Component({
    template: `
    <div id=item{{_idx}} style="border: 1px solid red">Test Component   
      <input type="text"/> 
      <button (click)="remove()">Remove</button> 
      <button (click)="add1()">Add</button>
    </div>`
})
class DynamicCmp {
    _ref: ComponentRef;
    _idx: number;
    constructor(private resolver: ComponentResolver, private location:ViewContainerRef) { }
    remove() {
        this._ref.destroy();
    }
    add1() {

  this.resolver.resolveComponent(DynamicCmp).then((factory:ComponentFactory<any>) => {
      let ref = this.location.createComponent(factory, 0);
//        this._dcl.loadNextToLocation(DynamicCmp, this._e).then((ref) => {
            ref.instance._ref = ref;
            ref.instance._idx = this._idx++;
        });
    }
}


@Component({
    selector: 'my-app',
    template: `
<button (click) = "add()" > Add new component </button >
<button (click) = "submit()" > Submit </button >
<button (click) = "removeall()" > Remove All </button >
<div class="ttt11" id="ttt" #location ></div>
`    
})
export class AddRemoveDynamic {
    idx: number = 0;

    @ViewChild('location', {read: ViewContainerRef}) location:ViewContainerRef;

    constructor(private resolver: ComponentResolver) { }

    add() {
  this.resolver.resolveComponent(DynamicCmp).then((factory:ComponentFactory<any>) => {
      let ref = this.location.createComponent(factory)

//        this._dcl.loadIntoLocation(DynamicCmp, this._e, 'location').then((ref) => {
            ref.instance._ref = ref;
            ref.instance._idx = this.idx++;
        });
    }

    submit(){
    }
}

Could you please help me on this?

Much Appreciate your support. Thanks in Advance.


Solution

  • You need to keep track of the dynamic components you create in the parent component.

    export class AddRemoveDynamic {
        private components = [];
    

    Then when you create a new component, push its component ref into the components array

    add() {
      this.resolver.resolveComponent(DynamicCmp).then((factory:ComponentFactory<any>) => {
          let ref = this.location.createComponent(factory)
    
    //        this._dcl.loadIntoLocation(DynamicCmp, this._e, 'location').then((ref) => {
                ref.instance._ref = ref;
                ref.instance._idx = this.idx++;
                this.components.push(ref);
            });
        }
    

    Finally, when submitting just traverse the components array and extract it's input values.

    submit(a: any){
          let componentThings = this.components.map((compRef) => compRef.instance.thing);
          alert(componentThings);
        }
    

    Working plunker