在Angular 2中捕获ng-content上的事件

时间:2017-03-02 11:32:25

标签: angular angular2-ngcontent

我正在通过this tutorial来理解角2的ng-content。我想捕获ng-content上触发的事件。我有以下组件:

@Component({
    moduleId: module.id,
    selector: 'card',
    template: `
    <ng-content (click)="onClick($event)"></ng-content>
    `
})
export class CardComponent {

    onClick(){
        console.log('clicked');
    }
}

在这里,您可以看到我正在设置click事件的监听器。但由于某些原因,它并没有触发。似乎替换了整个ng-content标记。因此,为了捕捉目前我正在做的事件:

template: `
    <div (click)="onClick($event)">
      <ng-content></ng-content>
    </div>
    `

有没有更好的方法呢?因为我不想将ng-content包裹到div中以避免样式问题。谢谢。 Plnkr

3 个答案:

答案 0 :(得分:3)

您可以使用@ContentChild捕获投影组件的事件。

孩子:

@Component({
moduleId: module.id,
selector: 'card-child',
template: `
<div>Card Child component</div>
`
})
export class CardChildComponent {
     @Output customEvent:EventEmitter = new EventEmitter()
}

父母:

@Component({
moduleId: module.id,
selector: 'card',
template: `
<ng-content></ng-content>
`
})
export class CardComponent {
    @ContentChild(CardChildComponent) childComp: CardChildComponent;

    ngAfterContentInit() {
        this.childComp.addEventListener("click", ()=>{console.log("clicked"});
        //Below is handling of custom event
        this.childComp.customEvent.subscribe(()=>{console.log("clicked"});
    }
}

下面是注入组分的方式。

<card>
<card-child></card-child>
</card>

答案 1 :(得分:1)

通过使用主机声明将事件侦听器绑定到组件元素,可以获得完全相同的结果。

import { Component, HostListener } from '@angular/core';

@Component({
  selector: 'card',
  template: `<ng-content></ng-content>`
})
export class ButtonComponent {

  @HostListener('click', ['$event.target'])
  onClick(target) {
    console.log('Clicked on: ', target);
  }

}

答案 2 :(得分:0)

<ng-content>只是一个占位符,用于转换组件标记内的内容。 Angular取而代之。

避免使用DIV解决方案的唯一选择是创建自己的ng-content版本。

基本上,您只需创建一个空组件,并在模板中只放置一个<ng-content>标记。如果您调用该组件AppContentComponent(app-content),那么您可以在组件中

<app-content (click)="onClick()">
   <ng-content></ng-content>
</app-content>

当然,这有点令人费解,你最终将你的被抄送的内容包装成另一个标签(不是<div>,而是<app-content>),当然,最初你没有'请注意被<ng-content>包裹的内容,所以我想它可能适合你。