我有一个向项目添加单击事件的类,如下所示,当我单击该项目时,出现以下错误:
Uncaught TypeError: Cannot read property 'has' of undefined
DomElement
基本上是 HTMLElement
的包装器,如下所示。
class MyClass {
private static _elements: DomElement[] = [];
private static createClickHandlers() {
MyClass._elements.forEach(element => {
element.components.forEach(component => {
if (typeof component['click'] == 'function') {
element.element.addEventListener('click', component['click']);
}
});
});
}
}
这是我的 HTMLElement
的包装类,它上面有组件,这些组件只是扩展 Component
类的类。
class DomElement {
private _element: HTMLElement = null;
private _components: Component[] = [];
}
这是所有功能发生的地方,您可以看到它包含一个点击功能。
class AnotherComponent extends Component {
click(e) {
e.preventDefault();
// Throws an error:
console.log(this.class.has('monkey'));
}
start() {
// Works:
console.log(this.class.has('monkey'));
}
}
每当创建组件时,都会运行 init
函数,如下所示:
class Component {
public class = null;
public init(element) {
this.class = new Class();
this.class.element = element;
}
}
现在一切都已正确设置,但是当我单击该元素时,类项目未定义。我尝试将组件绑定(bind)到元素,但这没有任何帮助。
我还有一个可以放置在类中的 start
,当它运行时它不会抛出错误,它运行 has
函数没有问题。这在 DOMContentLoaded
上执行。
那么,是什么导致元素在单击某个项目时不在那里,但在页面加载时却在那里?
最佳答案
您添加点击处理程序而不绑定(bind)它,因此当调用它时,函数主体中的 this
不是 Component
的实例。
应该是:
class MyClass {
private static _elements: DomElement[] = [];
private static createClickHandlers() {
this._elements.forEach(element => {
element.components.forEach(component => {
if (typeof component['click'] === 'function') {
element.element.addEventListener('click', component['click'].bind(component));
}
});
});
}
}
另请注意,我已将 MyClass._elements
更改为 this._elements
。
此外,如果 Component
的所有子类都需要实现 click
方法,那么您最好将其添加为抽象:
abstract class Component {
public class = null;
public init(element) {
this.class = new Class();
this.class.element = element;
}
abstract click(event: MouseEvent): void;
}
关于javascript - 单击时无法读取属性 'has',但可以在页面就绪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41618760/