我的Angular 4应用程序中有一个通用的弹出式组件,为了正确处理弹出式显示,我需要监听document
上的全局点击事件。
应用程序中可能同时有许多弹出组件,当用户点击这些组件之外的某个位置时,我需要关闭它们。出于显而易见的原因(我应该只有一个监听器),我不应该从组件本身绑定到document:click
事件,所以我决定创建一个集中服务,它将监听全局DOM事件在文档上并命令弹出组件。
当弹出组件初始化时,它会将自己注册到服务中,当它被销毁时,它会自行注销。因此,该服务始终具有应用程序中所有弹出组件的列表。到目前为止它的效果很好。
但是,我尝试将Renderer2
注入我的集中服务,以便通过它的listen()
方法监听DOM事件,但它看起来像是&#39 ; s仅适用于组件注入,不适用于服务注入。
此外,@HostListener('document:click')
装饰器在服务中不起作用。
我的架构是否正确?服务听取DOM事件是不是一个坏主意?
另一种可能的解决方案是创建另一个组件而不是服务,但我不喜欢这种方法,因为它需要在某个地方手动添加应用程序,而服务是自动创建。
实施我的使用方案的最佳方式是什么?
答案 0 :(得分:2)
您应该使用Observable.fromEvent
创建与此类似的服务:
@Injectable()
export class DocService {
obs: Observable;
constructor(){
this.obs = Observable.fromEvent(document, 'click');
}
onClick(): Observable{
return this.obs;
}
}
然后订阅组件中的observable:
// here I just log the event, in your case, you close the popoup
this.docService.onClick().subscribe(console.log, console.log);
你可能需要确保点击不会弹出你的弹出窗口。你可以处理这是你的订阅方法。