是否可以在服务中使用 HostListener?或者如何在 Angular 服务中使用 DOM 事件? [英] Is it possible to use HostListener in a Service? Or how to use DOM events in an Angular service?

查看:20
本文介绍了是否可以在服务中使用 HostListener?或者如何在 Angular 服务中使用 DOM 事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个检测所有键盘输入的服务,根据可配置的映射将击键转换为动作,并公开各种元素可以绑定到的 observables 以对特定的按键做出反应.

以下是迄今为止我的代码的简化,当 HostListener 在组件中时它可以工作,但现在我已经将它移到了一个服务中,即使它确实已初始化,它也永远不会触发.在服务中不能检测到这样的输入吗?

import { Injectable, HostListener } from '@angular/core';从rxjs/主题"导入{主题};@Injectable()导出类 InputService {@HostListener('window:keydown', ['$event'])键盘输入(事件:任何){控制台日志(事件);}}

解决方案

似乎无法在服务中使用 HostListener.

更新

就像 Stanislasdrg Reinstate Monica 写的那样,使用渲染器..

@Injectable()导出类 MyMouseService 实现 OnDestroy {私人 _destroy$ = 新主题();public onClick$: Observable;构造函数(私有 rendererFactory2:RendererFactory2){const renderer = this.rendererFactory2.createRenderer(null, null);this.createOnClickObservable(renderer);}ngOnDestroy() {this._destroy$.next();this._destroy$.complete();}私有 createOnClickObservable(渲染器:Renderer2){让 removeClickEventListener: () =>空白;const createClickEventListener = (处理程序:(e:事件)=>布尔值 |空白) =>{removeClickEventListener = renderer.listen("document", "click", handler);};this.onClick$ = fromEventPattern(createClickEventListener, () =>移除ClickEventListener()).pipe(takeUntil(this._destroy$));}}

现场演示:https://stackblitz.com/edit/angular-so4?file=src%2Fapp%2Fmy-mouse.service.ts

你可以使用旧的方式 window.addEventListener 就像@yurzui 已经指出的那样.

https://plnkr.co/edit/tc53cvQDfLHhaR68ilKr?p=preview

从@angular/core"导入 {Component, NgModule, HostListener, Injectable}从@angular/platform-b​​rowser"导入 {BrowserModule}@Injectable()导出类 MyService {构造函数(){window.addEventListener('keydown', (event) => {控制台目录(事件);});}}@成分({选择器:'我的应用',模板:`<div><h2>你好{{name}}</h2>

`,})出口类应用{构造函数(私有_srvc:MyService){this.name = 'Angular2'}}@NgModule({进口:[浏览器模块],声明:[应用程序],提供者:[MyService],引导程序:[应用程序]})导出类 AppModule {}

I want to create a service which detects all keyboard input, translates the key strokes into actions based on a configurable mapping, and exposes observables which various elements can bind to to react to specific key presses.

The following is a simplification of my code so far, it worked when HostListener was in a component, but now I've moved it into a service it never fires even though it is definitely initialised. Is it not possible to detect input like this in a service?

import { Injectable, HostListener } from '@angular/core';

import { Subject } from 'rxjs/Subject';

@Injectable()
export class InputService {

    @HostListener('window:keydown', ['$event'])
    keyboardInput(event: any) {
        console.log(event);
    }
}

解决方案

Seems like its not possible to use HostListener in a service.

UPDATE

like Stanislasdrg Reinstate Monica wrote, there's a more elegant and more angular way using the renderer..

@Injectable()
export class MyMouseService implements OnDestroy {
  private _destroy$ = new Subject();

  public onClick$: Observable<Event>;

  constructor(private rendererFactory2: RendererFactory2) {
    const renderer = this.rendererFactory2.createRenderer(null, null);

    this.createOnClickObservable(renderer);
  }

  ngOnDestroy() {
    this._destroy$.next();
    this._destroy$.complete();
  }

  private createOnClickObservable(renderer: Renderer2) {
    let removeClickEventListener: () => void;
    const createClickEventListener = (
      handler: (e: Event) => boolean | void
    ) => {
      removeClickEventListener = renderer.listen("document", "click", handler);
    };

    this.onClick$ = fromEventPattern<Event>(createClickEventListener, () =>
      removeClickEventListener()
    ).pipe(takeUntil(this._destroy$));
  }
}

live-demo: https://stackblitz.com/edit/angular-so4?file=src%2Fapp%2Fmy-mouse.service.ts

OLD

You could use the old way window.addEventListener like @yurzui pointed out already.

https://plnkr.co/edit/tc53cvQDfLHhaR68ilKr?p=preview

import {Component, NgModule, HostListener, Injectable} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Injectable()
export class MyService {

  constructor() {
    window.addEventListener('keydown', (event) => {
      console.dir(event);
    });
  }

}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
    </div>
  `,
})
export class App {

  constructor(private _srvc: MyService) {
    this.name = 'Angular2'
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App ],
  providers: [MyService],
  bootstrap: [ App ]
})
export class AppModule {}

这篇关于是否可以在服务中使用 HostListener?或者如何在 Angular 服务中使用 DOM 事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆