Using service to listen for DOM events in Angular

我的梦境 提交于 2019-12-08 13:55:58

问题


I have a generic pop-up component in my Angular 4 application and in order to correctly handle popup display I need to listen for global click events on the document.

There could be many pop-up components at the same time in the application and I need to close them when user clicks somewhere outside of the those components. I shouldn't bind to document:click event from the component itself for obvious reasons (there should be only one listener), so I've decided to create a centralized service, which would listen for global DOM events on the document and to command the pop-up components.

When pop-up component is initialized, it registers itself with the service and when it's destroyed it deregisters itself. So, the service always has a list of all pop-up components in the application. So far it works great.

However, I've tried to inject the Renderer2 to my centralized service in order to listen for DOM events via it's listen() method, but it looks like it's only available for component injection, not for service injection.

Also, the @HostListener('document:click') decorator is not working in services.

Is my architecture correct? Is it a bad idea for service to listen for DOM events?

The other possible solution would be to create another component instead of the service, but I don't like this approach, because it will require it's manual addition to the application somewhere in contrast with service which is automatically created.

What would be the best way to implement my usage scenario?


回答1:


You should use Observable.fromEvent

sample plunker: https://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5

Create a service similar to this one:

@Injectable()
export class DocService {
  obs: Observable;

  constructor(){
    this.obs = Observable.fromEvent(document, 'click');
  }

  onClick(): Observable{
    return this.obs;
  }
}

then subscribe to the observable in your component:

// here I just log the event, in your case, you close the popoup
this.docService.onClick().subscribe(console.log, console.log);

you'll probably need to make sure the click is not hapening on your popup. You can handle this is your subscribe method.



来源:https://stackoverflow.com/questions/44466404/using-service-to-listen-for-dom-events-in-angular

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!