angular2 从动态 child 到 parent 发出事件

angular2 emit event from dynamic child to parent

我在 parent 模板中有 child 元素。 Child 是动态添加的。从 child 我想调用 parents 函数,它添加了另一个 child。我为此使用 @Output,它有效,当 child 是静态的,但浏览器无法编译页面,当动态添加 child 时:

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>

您需要在新组件中传递一些回调函数。

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

然后你可以在组件内部调用你的回调

this.loadComponent();

由于您是动态创建组件,因此需要连接任何活动以传递输入并侦听输出。要在您的案例中连接输出,您只需要另一条线来连接监听事件:

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

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

您还需要删除模板中连接监听器的内容,因为它无效(即 (loadComponent)="loadDragDropComponent($event)")。