javascript - 当我们删除 HostListener 时,Angular HTML 绑定不起作用
问题描述
为了减少更改检测,我们将 hostlistener 替换为来自 RXJS 的事件和 angular 的 runoutside。
这就是我的角度代码的样子
ngOnInit() {
this.windowKeyDown();
// this.subject$ = this.subject.asObservable();
}
constructor(private _ngZone: NgZone) {}
//@HostListener('window:keydown', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
console.log('handle key fired');
this.keypressed = event.key;
this.iskeyPressed = true;
}
windowKeyDown() {
console.log('windowKeyDown');
fromEvent(window, 'keydown')
.pipe(this.outsideZone(this._ngZone))
.subscribe(event => this.handleKeyboardEvent(<KeyboardEvent>event));
}
outsideZone<T>(zone: NgZone) {
return function(source: Observable<T>) {
return new Observable(observer => {
let sub: Subscription;
zone.runOutsideAngular(() => {
sub = source.subscribe(observer);
});
return sub;
});
};
}
和 HTML 绑定是:
<h2>keypressed: {{keypressed}}</h2>
<h2>iskeyPressed: {{iskeyPressed}}</h2>
在这个绑定变量中它自己现在没有更新,你能指导我的代码有什么问题吗?
复制的最小步骤:https ://stackblitz.com/edit/keypress-example-vu3mej?file=app%2Fapp.component.html
解决方案
我建议将此组件的 ChangeDetectionStrategy 设置为 OnPush。你可以在这里阅读更多关于它的信息。不要在此组件中放置任何您希望自动更改检测的逻辑,因为整个组件都禁用了更改检测。
下面是一个代码示例,展示了如何直接从模板订阅键盘事件(使用异步管道)。
import {
Component,
Input,
ChangeDetectionStrategy,
OnInit
} from '@angular/core';
import { fromEvent, Observable } from 'rxjs';
import { map, startWith, tap } from 'rxjs/operators';
@Component({
selector: 'child',
template: `
<ng-container *ngIf="keyboard$ | async as keyBoard">
<h2>keypressed: {{ keyBoard.keypressed }}</h2>
<h2>iskeyPressed: {{ keyBoard.iskeyPressed }}</h2>
</ng-container>
`,
styleUrls: [],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent implements OnInit {
keyboard$: Observable<{ keypressed: any; iskeyPressed: boolean }>;
ngOnInit() {
console.log('bla')
this.keyboard$ = fromEvent(window, 'keydown').pipe(
map(event => ({ keypressed: event.key, iskeyPressed: true })),
startWith({keypressed: null, iskeyPressed: null})
);
}
}
推荐阅读
- c# - Asp.Net Core 与 Angular 数据压缩方法
- angular - Angular Datatables 以编程方式选择行
- bash - Bash 字符串替换“”
- sparql - 获取实例 - Protege 中的 SPARQL 查询
- react-native - react-native-linear-gradient (-lBVLinearGradient) 上的 React Native Xcode 构建错误
- sql - SQL Server RESTORE VERIFY ONLY 签出但不能从备份中恢复
- c# - 如何在不嵌套的情况下将一类对象序列化为参数列表
- java - 我需要在我的 java ee 应用程序中简化 jdbc 连接。我想在 Spring 中重写。它创建了太多的静态连接
- ruby-on-rails - 使用