Search code examples
angularangular2-componentsangular2-output

Can output events be fired for dynamically created components


What I'm trying to do:

  1. Create components dynamically (done)
  2. Allow the dynamically created components to leverage "outputs" so that parent Components can listen for changes from the children.

Here is a Plnkr for what I'm trying do to. Plnker -> https://plnkr.co/edit/XpDCGIwd2at9oR74lpY5?p=preview

When the user Clicks "+ Component" the following creates the component

let componentFactory = this.componentFactoryResolver.resolveComponentFactory(ChildComponent);
let ref = this.container.createComponent(componentFactory);

Within each child component that is added, when the user clicks the "Fire Event"

<span class="initiateParentAction" 
  (click)="fireEventEmitter()" [class.eventFired]="eventFired==true">Fire Output Event: {{eventFired}}</span>

it calls the following

fireEventEmitter(){
    console.log("Event Fired");
    this.parentActionReq.emit({
      action: "helloWorld"
    });
    this.eventFired = true;
    setTimeout(() => this.eventFired=false, 2000);
}

The parent component (in this case "App" component), is listening for these Outputs as shown here

<ng-container #container 
    (parentActionReq)="childActionInitiated($event)"></ng-container>

I have been unable to get events from Dynamically created components to register with the parent. In the Plnker, the "Received child output Event" should turn to true.

At this point, I'm thinking that due to the fact that these components are added at runtime, I need to somehow re-initialize event detection OnInit. But have made no headway.

Any suggestions, hints, guidance would be appreciated here.

I'm hesitant to go down the path of creating my own Observables, as this seems like it would be re-creating the wheel, the Output serves my purpose exactly.

Thank you kindly.


Solution

  • No, dynamically added components don't support binding to inputs or outputs. You can set and read data imperatively though.

    ref.instance.someProp = 'someVal';
    ref.instance.someOutput.subscribe(val => this.prop = val);
    

    See also Angular 2 dynamic tabs with user-click chosen components