Захват события на нг-контенте в Angular 2
Я прохожу этот урок, чтобы понять угловые 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
2 ответа
Вы можете достичь почти того же результата, привязав слушателей событий к элементу компонента с помощью объявления хоста.
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);
}
}
Вы можете использовать @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>
<ng-content>
это просто заполнитель для включения содержимого в теги компонента. Angular заменяет его.
Единственная возможность избежать использования DIV
решение, было бы создать свою собственную версию ng-content
,
По сути, вы просто создаете пустой компонент и в шаблоне <ng-content>
тег. Если вы называете этот компонент AppContentComponent
(приложение-контент), то вы можете, в ваших компонентах,
<app-content (click)="onClick()">
<ng-content></ng-content>
</app-content>
Конечно, это немного запутанно, и вы в конечном итоге оборачиваете свой включенный контент в другой тег (не <div>
, но <app-content>
), хотя, конечно, изначально вы не возражали против <ng-content>
так что я думаю, что это может сработать для вас.