我有一个自定义模式组件,它使用<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事件,这样就发生了,但是主机监听器失败了。想法?
我放弃了这种方法,转而使用共享服务,但我遇到了.next()
未向订阅者提供价值的问题:Subscriber doesn't receive value from .next()
答案 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
});
}
}
这对我来说适用,为了完整性起见也包括在内。