捕获<ng-content>中的组件发出的事件?

时间:2017-01-25 18:03:23

标签: angular events

我有一个自定义模式组件,它使用<ng-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 {
    . . .
}

<ng-content>的内容中,我有一个发出open事件的组件:

@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();
        }
    }

}

但是,ModalContainerComponent永远不会收到该事件。

例如:

即将到来。我做错了什么?

更新

由于@Output事件没有冒泡,我决定使用自定义指令来发出事件:

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 })]);
  }

}

使用:in Angular2 how to know when ANY form input field lost focus作为示例。

但是,我仍然无法在ModalContainerComponent中选择自定义事件:

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

我可以记录click事件,这样就发生了,但是主机监听器失败了。想法?

更新2

我放弃了这种方法,转而使用共享服务,但我遇到了.next()未向订阅者提供价值的问题:Subscriber doesn't receive value from .next()

4 个答案:

答案 0 :(得分:2)

您可以使用@ContentChild()获取登录模式的实例并手动订阅open事件

@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
        });
    }
}

答案 1 :(得分:1)

我最终放弃了事件驱动的方法,转而使用共享服务类。

答案 2 :(得分:0)

Angular中的事件发射器没有冒泡。如果您想要一个冒泡的活动,您应该使用CustomEvent创建一个活动。 在您的情况下,只有在组件本身上注册时,事件才会起作用:


System.Threading.Thread.CurrentPrincipal

答案 3 :(得分:0)

只需扩展rob'a答案和评论

@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
        });

    }
}

这对我来说适用,为了完整性起见也包括在内。