Search code examples
inputangularoutputeventemitter

Angular2 dynamiccomponentloader parameters for @Output


To my understanding, the way you set @Input variables for the component you just added to the DOM with DynamicComponentLoader, is that you use the promise block after invoking something like loadIntoLocation:

this.dcl.loadIntoLocation( Lorem, this.elRef, 'target')
            .then( cmpRef => {

                cmpRef.instance.foo = _self.baz;
            });


export class Lorem {
    public @Input()  foo : String;
    ...

My questions is how do you set the @Output when using dynamiccomponentloader?

this.dcl.loadIntoLocation( Lorem, this.elRef, 'target')
            .then( cmpRef => {

                cmpRef.instance.foo = _self.baz;
                cmpRef.instance.changer = _self.change($event);
            });



export class Lorem {
    public @Input()  foo            : String;
           @Output() changer = new EventEmitter();
    ...
    ...
    this.changer.emit("event");

I am very grateful for help you could offer.


Solution

  • I would leverage subscribe method instead link to result of _self.change($event) function like following:

    cmpRef.instance.changer.subscribe(($event) => _self.change($event));
    

    Since beta.16 loadIntoLocation was removed, in my example i will use loadNextToLocation wich takes a ViewContainerRef.

    App component

    import {Component, DynamicComponentLoader, ViewChild, ViewContainerRef} from 'angular2/core';
    
    @Component({
      selector: 'my-app',
      providers: [],
      template: `
        <div>
          <h2>Hello {{name}}</h2>
          <div #target></div>
        </div>
      `,
      directives: []
    })
    export class App {
      baz: string = "Test string";
      @ViewChild('target', {read: ViewContainerRef}) target : ViewContainerRef;
      constructor(private dcl: DynamicComponentLoader) {
        this.name = 'Angular2'
      }
      ngAfterViewInit() {
        this.dcl.loadNextToLocation(Lorem, this.target)
          .then(cmpRef => {
            cmpRef.instance.foo = this.baz;
            cmpRef.instance.changer.subscribe(($event) => this.change($event));
          });
      }
      change($event) {
        alert($event);
      }
    }
    

    Lorem component

    import {Component, Input, Output, EventEmitter} from 'angular2/core';
    
    @Component({
      selector: 'lorem',
      template: `
      <div>{{foo}}</div>
      <button (click)="run()">Run</button>`
    })
    class Lorem {
      @Input() foo: String;
      @Output() changer = new EventEmitter();
      run() {
        this.changer.emit("event from child");
      }
    }
    

    See plunker example

    Hope it helps you.