`e: TouchEvent` 的 `@HostListener` 导致 Firefox 崩溃并出现“ReferenceError: TouchEvent 未定义”。
2018-07-01
1794
使用
@HostListener
并将事件参数明确类型为
TouchEvent
,会导致 Firefox 崩溃并显示以下错误消息:
ReferenceError: TouchEvent is not defined.
示例:
@HostListener('touchstart', ['$event']) // or 'touchend', 'touchmove'
onTouchStart(e: TouchEvent): void {}
我可以想出几种方法来防止这种情况发生:
-
使用
e: TouchEvent | any
或e: any
(或者根本不指定类型) -
使用
elRef.nativeElement.addEventListener('touchstart', (e: TouchEvent) => {})
-
使用
Observable.fromEvent(elRef.nativeElement, 'touchstart').subscribe((e: TouchEvent) => {})
但使用
any
或
| any
似乎是一种 hack,而其他两个选项没有利用框架。
是否有其他更好、更安全的方法来处理此问题?如果没有,哪种方法更可取?
(也许有人可以解释 Angular 实际上在做什么,以及为什么只有当事件明确类型为
TouchEvent
时才会发生此错误...)
编辑:此问题在 Angular 7 中仍然存在。
编辑:
此问题显然已在 Angular 6 中得到修复。
2个回答
当方法上有装饰器时,typescript 编译器会将参数类型存储在元数据中,这在桌面版 Firefox 中会失败,因为 TouchEvent 未在此处定义。可以通过使用存根填充缺失的类型来解决此问题。只需将以下代码添加到
polyfills.ts
for (const type of ['TouchEvent']) {
if (typeof window[type] === 'undefined') {
window[type] = function () { };
}
}
要填充其他类型,请将它们添加到列表中。请注意 - 这可能会破坏通过检测
window.TouchEvent
来检查触摸事件是否存在的代码。
无论如何,该问题似乎只发生在 JIT 编译器中,因此它可能会随着 Ivy 而消失。
IztokK
2020-10-28
您可以告诉 Angular 不要在 tsconfig.json 中发出装饰器元数据:
"emitDecoratorMetadata": false
waterplea
2019-03-19