简体   繁体   中英

angular2 emit event from dynamic child to parent

I have child element in parent template. Child is added dynamically. From child I want to call parents function, which adds another child. I use @Output for this, it works, when child is static, but browser is unable to compile the page, when child is added dynamically:

Parent:

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

loadDragDropComponent() {        
    let componentFactory = this.componentFactoryResolver.resolveComponentFactory(
      DragDropComponent
    );        
    let componentRef = this.viewContainerRef.createComponent(componentFactory);                
  }

Parent HTML:

 <div *ngIf="repair_picture" fxLayoutAlign.xs="center" fxLayoutWrap="wrap">
            <!-- static works -->
            <pd-drag-drop (loadComponent)="loadDragDropComponent($event)"></pd-drag-drop>
            <!-- dynamic does not works-->
            <ng-template #dragdrophost (loadComponent)="loadDragDropComponent($event)"></ng-template>
        </div>

Child:

   export class DragDropComponent implements OnInit {
  @Output() loadComponent = new EventEmitter<string>();
......
this.loadComponent.emit('loadComponent');
}
Compiler error:
Event binding loadComponent not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("eady shown, it is possible to dynamically load component-->
                    <ng-template #dragdrophost [ERROR ->](loadComponent)="loadDragDropComponent($event)"></ng-template>

Since you are dynamically creating the component, you need to wire up any activities to pass the inputs and listen to the outputs. To wire up the output in your case, you'll just need another line to wire up listening to the event:

loadDragDropComponent() {        
  let componentFactory = this.componentFactoryResolver.resolveComponentFactory(
    DragDropComponent
  );

  let componentRef = this.viewContainerRef.createComponent(componentFactory);
  componentRef.instance.loadComponent.subscribe($event => {
    this.loadDragDropComponent($event)
  });
}

You'll also need to remove that stuff in your template that is wiring up the listener since that isn't valid (ie (loadComponent)="loadDragDropComponent($event)" ).

You need to pass some callback function inside your new component.

let componentRef = this.viewContainerRef.createComponent(componentFactory);
componentRef.instance.loadComponent = function() {
    // put your code here
}

And then you can call your callback inside component

this.loadComponent();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM