简体   繁体   English

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

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

I am trying to write an ES6 class for an interactive calendar on my current project. 我正在尝试为当前项目的交互式日历编写ES6类。

The Class looks similar to the below: 该类看起来类似于以下内容:

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;

I know that the context of the 'this' keyword has changed from the constructor to the button which has been clicked within the method1 function. 我知道'this'关键字的上下文已从构造函数更改为已在method1函数中单击的按钮。 However I don't know how to keep the context of the button and the constructor within the same function. 但是我不知道如何将按钮和构造函数的上下文保持在同一个函数中。 I tried changing the button event listener code to the following: 我尝试将按钮事件侦听器代码更改为以下内容:

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

But this just switches the context of the 'this' keyword to the constructor rather than the button. 但这只是将'this'关键字的上下文切换到构造函数而不是按钮。 I need to use both in my function. 我需要在我的功能中使用它们。

Any ideas? 有任何想法吗? I'm hoping this is quite a common issue? 我希望这是一个非常普遍的问题?

You could create a closure that would send the event and the button. 您可以创建一个发送事件和按钮的闭包。 The closure would keep the this context and send the button as well 闭包将保持此上下文并发送按钮

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

Since you are using ES6, have you tried using an arrow function ? 由于您使用的是ES6,您是否尝试过使用箭头功能

An arrow function expression has a shorter syntax than a function expression and does not bind its own this, arguments, super, or new.target. 箭头函数表达式具有比函数表达式更短的语法,并且不绑定它自己的this,arguments,super或new.target。 These function expressions are best suited for non-method functions, and they cannot be used as constructors. 这些函数表达式最适合非方法函数,不能用作构造函数。

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

You have a few options: 你有几个选择:

You can bind the methods themselves: 您可以绑定方法本身:

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

There's the bind operator if you're using Babel (or some other transpiler). 如果您正在使用Babel (或其他一些转换器),那么就有绑定运算符 It hasn't been accepted into the standard yet, so I'd be weary of using it. 它尚未被标准接受,所以我厌倦了使用它。 Using the bind operator, you can do the equivalent: 使用bind运算符,您可以执行等效操作:

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

The other option is to do what you've done already, just corrected. 另一种选择是做你已经完成的事情,只是纠正了。

You have to bind the method, not the result of the forEach. 您必须绑定方法,而不是forEach的结果。

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

or with bind op: 或者使用bind op:

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

Finally, you also have the option of creating a wrapper function using arrow notation for lexical scope: 最后,您还可以选择使用箭头符号为词法范围创建包装函数:

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

And if you use ES6, you can also use for of instead of forEach. 如果您使用ES6,您也可以使用for而不是forEach。 This prevents creating yet another callback with its own scope. 这可以防止使用自己的范围创建另一个回调。 In this code, the keyword 'this' still refers to the original class. 在此代码中,关键字“this”仍指代原始类。

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

Try using a lambda expression to set the delegate of your event as well. 尝试使用lambda表达式来设置事件的委托。 Something like below: 如下所示:

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

You can use bind to create a partial function: 您可以使用bind来创建部分函数:

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

It works assuming you change method1 to be: 假设您将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