tre*_*ron 24 angular2-services angular
我想创建一个检测所有键盘输入的服务,将关键笔划转换为基于可配置映射的操作,并公开各种元素可以绑定的可观察对特定按键的反应.
以下是我的代码到目前为止的简化,它在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);
}
}
Run Code Online (Sandbox Code Playgroud)
mxi*_*xii 24
似乎不可能在服务中使用它.
你必须使用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 {}
Run Code Online (Sandbox Code Playgroud)
Get*_*awn 16
HostListener只能添加到组件/指令中,因此要将侦听器添加到服务,您可以fromEvent使用rxjs.
import { fromEvent } from 'rxjs';
@Injectable()
export class InputService implements OnDestroy {
// Watch for events on the window (or any other element).
keyboardInput$ = fromEvent(window, 'keydown').pipe(
tap(evt => console.log('event:', evt))
)
// Hold a reference to the subscription.
keyboardSub?: Subscription;
constructor() {
// Subscribe to the property or use the async pipe.
// Remember to unsubscribe when you are done if you don't use the async pipe (see other example).
this.keyboardSub = this.keyboardInput$.subscribe();
}
ngOnDestroy() {
// Destroy the subscription.
this.keyboardSub?.unsubscribe();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过将订阅逻辑移至组件模板来删除订阅逻辑,然后只在服务中包含可观察的内容。然后看起来像这样:
@Injectable()
export class InputService implements OnDestroy {
// Watch for events on the window (or any other element).
keyboardInput$ = fromEvent(window, 'keydown').pipe(
tap(evt => console.log('event:', evt))
)
}
@Component({
selector: 'my-selector',
providers: [InputService],
template: `
<ng-container *ngIf="keyboardInput$ | async">
<!-- Your content -->
</ng-container>
`
})
export class ExampleComponent {
keyboardInput$ = this.inputService.keyboardInput$;
constructor(private readonly inputService: InputService){}
}
Run Code Online (Sandbox Code Playgroud)
Sta*_*ica 10
注意:
瞭望台的内存泄漏的听众不会自动停止监听。
原始答案:
还有另一种方法,即使用RendererFactory2andRenderer2。我正在使用这样的服务来监控空闲情况并相应地注销用户。这是代码的一部分:
@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;
})
);
}
}
Run Code Online (Sandbox Code Playgroud)
通过将 null 传递给渲染器工厂,this.rendererFactory2.createRenderer(null, null)您可以获得默认的 DOMrenderer,因此可以侦听窗口事件。
| 归档时间: |
|
| 查看次数: |
7291 次 |
| 最近记录: |