我是 Angular 新手,并且在 Observables 方面遇到了困难。我搜索了我的问题,但没有找到我的确切问题的答案。 我正在尝试根据从商店获得的变量(可观察)来启用/禁用键盘事件。
...
isDisabled$: Observable<boolean> = this.store.select(selectIsDisabled);
private subscriptions = new Subscription();
constructor(
private store: Store<IStore>
) {
this.onKeyboardEvent();
}
...
// this.subscriptions is used in other functions
...
private onKeyboardEvent(): void {
let keys: string[] = [];
this.subscriptions.add(
fromEvent<KeyboardEvent>(document, 'keydown').pipe(
filter(key => key.repeat === false),
map(key => key.code)
).subscribe(keyCode => {
if (!keys.includes(keyCode)) {
keys.push(keyCode);
}
// Here we have keys pressed logic...
})
);
}
现在这是我的代码,我想要实现的是根据
isDisabled$
值启用/禁用键盘事件(我有一个按钮可以更改 isDisabled$ 值)。
我尝试订阅
isDisabled$
并在 isDisabled 为 false 时调用 this.onKeyboardEvent()
,但问题是这样。即使 isDisabled 为 true,订阅仍然有 fromEvent
事件。
当 isDisabled === true 时,我也尝试取消订阅
this.subscriptions
但这对我不起作用
我是 Angular 和 rxjs 的新手,我不知道是否有运算符可以实现此目的?
感谢您的帮助:)
combineLatest
:
keyDown$ = fromEvent<KeyboardEvent>(document, 'keydown').pipe(
map((key) => key.code)
);
filteredKeyDown$ = combineLatest([this.isDisabled$, this.keyDown$]).pipe(
filter(([isDisabled, _]) => !isDisabled),
map(([_, key]) => key)
);
takeUntilDestroyed
private onKeyboardEvent(): void {
this.filteredKeyDown$.pipe(takeUntilDestroyed()).subscribe(...);
}
显然我不知道你的确切用例,但也许你可以通过异步管道提供
isDisabled
属性作为输入信号?我不确定我没有测试过这一点。通过这样做,您可以避免处理订阅,这通常是更好的选择。
<app-component [isDisabled]="isDisabled$ | async"/>
...
isDisabled = input.required<boolean>();
@HostListener('document:keydown', ['$event'])
handleKeydown(event: KeyboardEvent) {
if (this.isDisabled()) return;
...
}