Capturing events emitted by components inside <ng-content>?
I have my own modal component that uses <ng-content> to transfer content:
@Component({ selector: 'modal-container', template: ` <div [class]="css"> <div [attr.id]="id" class="reveal" (open)="openModal()"> <ng-content></ng-content> </div> </div> ` }) export class ModalContainerComponent { . . . } In the content of <ng-content> , I have a component that emits an open event:
@Component({ selector: 'login-modal', template: ` <modal-container [id]="'login-modal'"> <section>...</section> </modal-container> `, }) export class LoginModalComponent implements OnInit { @Output() open = new EventEmitter(); ngOnInit(): void { // Here I am checking an ngrx store with code that is not included if (state.openLoginModal) { this.open.emit(); } } } however, the ModalContainerComponent never receives the event.
Examples such as:
approaching. What am I doing wrong?
Update:
Since @Output events @Output not bubble, I decided to go with a custom directive to emit an event:
import { Directive, ElementRef, Renderer } from '@angular/core'; @Directive({ selector: '[open-modal]', host: { '(click)': 'openModal()' } }) export class OpenModalDirective { constructor( private elementRef: ElementRef, private renderer: Renderer ) {} openModal(): void { this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'dispatchEvent', [new CustomEvent('open-modal-container', { bubbles: true })]); } } using in Angular2 how to find out when, as ANY form, input fields have lost focus as an example.
However, I still cannot pick up a custom event in ModalContainerComponent :
@HostListener('open-modal-container') openModalContainer(): void { console.log('openModal() was invoked'); } I can register a click event so that this happens, but the host listener is not working. Thoughts?
Update 2
I refuse this approach in favor of a common service, but I have a problem with .next() that does not provide value to the subscriber: The subscriber does not get the value from .next ()
You can get an instance of the login modality with @ContentChild() and manually subscribe to an open event
@Component({ selector: 'modal-container', template: ` <div [class]="css"> <div [attr.id]="id" class="reveal" (open)="openModal()"> <ng-content></ng-content> </div> </div> ` }) export class ModalContainerComponent { @ContentChild(LoginModalComponent) loginModal: LoginModalComponent; ngAfterViewInit() { this.loginModal.open.subscribe((event) => { //Handel event here }); } } Event listeners in Angular do not bubble. If you want an event that bubbled up, you must create an event with a CustomEvent . In your case, the event will work only if you register it on the component itself:
<login-modal (open)="func()"></login-modal> Just to expand on rob'a answer and comment
@ContentChild(LoginModalComponent) private models: QueryList<LoginModalComponent>; ngAfterViewInit() { let models = this.models.toArray(); for (let key in panels) { let model = models[key]; panel.open.subscribe(()=>{ // do things }); } } This works in my case and is included for completeness.