繁体   English   中英

ES6类 - 从事件处理程序中调用方法

[英]ES6 Class - Call method from within event handler

我正在尝试为当前项目的交互式日历编写ES6类。

该类看起来类似于以下内容:

class Calendar {

constructor (s) {

    this.eventButtons = s.eventButtons;
    this.eventButtons.forEach(button => button.addEventListener('click', this.method1);
    this.eventBoxes = s.eventBoxes;


method1 (e) {
    e.preventDefault();
    this.method2(e.target.href);
}

method2 (url) {
    console.log(url);
}

}


export default Calendar;

我知道'this'关键字的上下文已从构造函数更改为已在method1函数中单击的按钮。 但是我不知道如何将按钮和构造函数的上下文保持在同一个函数中。 我尝试将按钮事件侦听器代码更改为以下内容:

this.eventButtons.forEach(button => button.addEventListener('click', this.method1).bind(this);

但这只是将'this'关键字的上下文切换到构造函数而不是按钮。 我需要在我的功能中使用它们。

有任何想法吗? 我希望这是一个非常普遍的问题?

您可以创建一个发送事件和按钮的闭包。 闭包将保持此上下文并发送按钮

button => button.addEventListener('click', event => this.method1(event, button))

由于您使用的是ES6,您是否尝试过使用箭头功能

箭头函数表达式具有比函数表达式更短的语法,并且不绑定它自己的this,arguments,super或new.target。 这些函数表达式最适合非方法函数,不能用作构造函数。

method1 = (e) => {
    e.preventDefault();
    this.method2(e.target.href);
}

你有几个选择:

您可以绑定方法本身:

this.method1 = this.method1.bind(this);
this.method2 = this.method2.bind(this);

如果您正在使用Babel (或其他一些转换器),那么就有绑定运算符 它尚未被标准接受,所以我厌倦了使用它。 使用bind运算符,您可以执行等效操作:

this.method1 = ::this.method1
this.method2 = ::this.method2

另一种选择是做你已经完成的事情,只是纠正了。

您必须绑定方法,而不是forEach的结果。

this.eventButtons.forEach(button =>
    button.addEventListener('click', this.method1.bind(this)));

或者使用bind op:

this.eventButtons.forEach(button =>
    button.addEventListener('click', ::this.method1));

最后,您还可以选择使用箭头符号为词法范围创建包装函数:

this.eventButtons.forEach(button =>
    button.addEventListener('click', (...params) => this.method1(...params)));

如果您使用ES6,您也可以使用for而不是forEach。 这可以防止使用自己的范围创建另一个回调。 在此代码中,关键字“this”仍指代原始类。

this.eventButtons = s.eventButtons;
for(b of this.eventButtons){
   b.addEventListener('click', () => this.method1);
}

尝试使用lambda表达式来设置事件的委托。 如下所示:

button.addEventListener('click', (e) => { e.preventDefault(); this.method2(); });

您可以使用bind来创建部分函数:

this.eventButtons.forEach(button => button.addEventListener('click', this.method1.bind(this, button));

假设您将method1更改为:

method1 (button, e) {
  e.preventDefault();
  this.method2(e.target.href);
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM