2017-07-07 72 views
5

我正在尝试为当前项目上的交互式日历编写ES6类。ES6类 - 从事件处理程序中调用方法

的Class看起来类似于下面:

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; 

我知道,“这个”关键字的上下文从构造改为已被点击方法1函数内的按钮。但是我不知道如何保持按钮和构造函数的上下文在同一个函数中。我尝试将按钮事件监听器代码更改为以下代码:

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

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

任何想法?我希望这是一个很常见的问题?

+0

的[无法调用它在ES6在Node.js的限定它的一类内的方法](可能的复制https://stackoverflow.com/questions/39621821/cannot-call-a-method-within- a-class-it-defined-it-in-es6-in-node-js) – noahnu

回答

5

由于您使用的是ES6,您是否尝试过使用arrow function

箭头函数表达式具有比功能 表达较短的语法和不结合其自身的此,自变量,超级或 new.target。这些函数表达式最适合非方法 函数,并且它们不能用作构造函数。

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

虽然这不是ES6。它是[class-fields](https://github.com/tc39/proposal-class-fields)第2阶段提案 – CodingIntrigue

1

尝试使用lambda表达式来设置你的事件的委托为好。像下面这样:

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

你可以创建一个闭包来发送事件和按钮。闭合将保持这一背景下,并发送按钮以及

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

您可以使用bind使局部功能:

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

它的工作原理假设你改变method1是:

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

你缺少右括号。你的意思是绑定到什么地方? – noahnu

+0

谢谢,修正了它 – amiramw

3

您有几个选择:

您可以将方法Š自己:

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

那里,如果你正在使用Babel(或其他一些transpiler)是的bind operator。它尚未被纳入标准,所以我会厌倦使用它。使用绑定运算符,您可以执行以下等效操作:

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

另一个选项是完成已经完成的工作,只是已更正。

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

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

或绑定OP:

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

最后,您还可以使用箭头符号的词汇范围,建立一个包装功能的选项:

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

我刚试过你的建议:this.eventButtons.forEach(button => button.addEventListener('click',this.method1.bind(this)));这使得'this'关键字的上下文成为构造函数。这很棒。但是,我如何参考按钮? –

+1

@JamesHowell'e.currentTarget'或'e.target' - 与你已经有的相同 – CodingIntrigue

+1

@noahnu绑定语法'::'仍然是阶段0 - 不是ES7 – CodingIntrigue

2

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

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