angular - 是否可以在服务中使用 HostListener?或者如何在 Angular 服务中使用 DOM 事件?

标签 angular angular2-services

我想创建一个服务来检测所有键盘输入,将击键转换为基于可配置映射的操作,并公开各种元素可以绑定(bind)到的可观察对象以对特定按键使用react。

以下是到目前为止我的代码的简化,它在 HostListener 位于组件中时有效,但现在我已将其移至服务中,即使它已明确初始化也永远不会触发。在服务中不可能检测到这样的输入吗?

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

最佳答案

似乎无法在服务中使用 HostListener

更新

喜欢Stanislasdrg Reinstate Monica写道,使用 renderer 有一种更优雅、更有棱 Angular 的方式..

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

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

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

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 {}

关于angular - 是否可以在服务中使用 HostListener?或者如何在 Angular 服务中使用 DOM 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39592972/

相关文章:

typescript - 找不到模块 'rxjs/subject/BehaviorSubject'

angular - 对 Observable 的订阅永远不会触发

Angular 2 : Property 'toPromise' does not exist on type 'Observable<Response>'

angular - 如何在 angular4 中读取 APP_INITIALIZER 服务中的查询参数?

angular - 当服务实际存在于提供者中时,没有提供服务

angular - 如何升级 Angular CLI 项目?

javascript - 如果我们无法从父组件更改属性或操作它们,那么 @ViewChild 有什么用呢?

angular - Ionic 3 输入掩码

dependency-injection - angular2 向其他人注入(inject)服务 - 使用@Inject 时出错

javascript - mixLatest 与 ngrx 不更新更改