是否可以在服务中使用HostListener?

问题描述 投票:18回答:2

我想创建一个检测所有键盘输入的服务,将关键笔划转换为基于可配置映射的动作,并公开各种元素可以绑定的可观察对特定按键的反应。

以下是我的代码到目前为止的简化,它在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);
    }
}
angular angular2-services
2个回答
22
投票

似乎不可能在服务中使用它。

你必须使用像@yurzui指出的旧方式window.addEventListener

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

0
投票

通过使用rendererFactory2和renderer2,还有另一种方法。我正在使用这样的服务来监视空闲并相应地注销用户。以下是代码的一部分:

@Injectable()
export class IdleService {

  renderer: Renderer2;
  lastInteraction: Date = new Date();
  definedInactivityPeriod = 10000;

  constructor(
    private rendererFactory2: RendererFactory2,
    private auth: AuthService,
    private router: Router
  ) {
    this.renderer = this.rendererFactory2.createRenderer(null, null);
    this.renderer.listen('document', 'mousemove', (evt) => {
      console.log('mousemove');
      this.lastInteraction = new Date();
    });
    // Subscribing here for demo only
    this.idlePoll().subscribe();
  }

  idlePoll() {
    return interval(1000)
      .pipe(
        tap(() => console.log('here', new Date().getTime() - this.lastInteraction.getTime())),
        takeWhile(() => {
          if ((new Date().getTime() - this.lastInteraction.getTime()) > this.definedInactivityPeriod) {
            this.auth.logout();                        
          }
          return (new Date().getTime() - this.lastInteraction.getTime()) < this.definedInactivityPeriod;
        })
      );
  }

}

通过将null传递给渲染器工厂this.rendererFactory2.createRenderer(null, null),您可以获得默认的DOMrenderer,因此可以监听窗口事件。

© www.soinside.com 2019 - 2024. All rights reserved.