Capturing events emitted from components inside <ng-content>?

I have a custom modal component which uses <ng-content> to transclude 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 contents of <ng-content> I have a component which emits the 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:

are coming up short. What am I doing wrong?


Update:

Since @Output events don't bubble, I decided to go with a custom directive to emit the 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 know when ANY form input field lost focus as an example.

However, I still can't pick up the custom event in ModalContainerComponent:

@HostListener('open-modal-container')
openModalContainer(): void {
  console.log('openModal() was invoked');
}

I can log the click event, so that's happening, but the host listener is failing. Thoughts?


Update 2

I'm abandoning this approach in favor of a shared service, but I'm running into an issue with .next() not providing a value to the subscriber: Subscriber doesn't receive value from .next()


ANSWERS:


You could get an instance of the login modal with @ContentChild() and manually subscribe to the 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 emitters in Angular are not bubbling up. If you want an event that bubbling up, you should create an event with CustomEvent. In your case the event will work only if your register it on the component itself:

<login-modal (open)="func()"></login-modal>

I ended up abandoning the event-driven approach and went with a shared service class instead.



 MORE:


 ? Swift IndexPath counting continuous over multiple sections?
 ? How to draw segments (geom_segment) dynamically in R ggplot?
 ? How to create C# dynamic object?
 ? How can I move my labels to the right with CSS?
 ? Javafx I want to remove the dynamic element in Accordion
 ? Dynamic MVC Model Server side validation
 ? laravel 5.4 dynamic database connection
 ? How to initialize a char array as null within a default constructor?
 ? Java Play Framework creating logged in navigation bar - inserting dynamic html in scala template
 ? Dynamic search and filtering in Excel