我正在尝试为我当前项目的交互式日历编写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'关键字的上下文切换到构造函数而不是按钮。我需要在我的功能中使用它们。
有什么想法吗?我希望这是一个非常普遍的问题吗?
答案 0 :(得分:7)
您可以创建一个发送事件和按钮的闭包。闭包将保持此上下文并发送按钮
button => button.addEventListener('click', event => this.method1(event, button))
答案 1 :(得分:5)
由于您使用的是ES6,您是否尝试使用arrow function?
箭头函数表达式的语法短于函数 表达式并不绑定它自己的this,arguments,super或 new.target。这些函数表达式最适合非方法 函数,它们不能用作构造函数。
method1 = (e) => {
e.preventDefault();
this.method2(e.target.href);
}
答案 2 :(得分:3)
您有几个选择:
您可以自己绑定方法:
this.method1 = this.method1.bind(this);
this.method2 = this.method2.bind(this);
bind operator如果您正在使用Babel(或其他一些转录程序),则会{{3}}。它还没有被标准接受,所以我厌倦了使用它。使用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)));
答案 3 :(得分:3)
如果您使用ES6,您也可以使用for而不是forEach。这可以防止使用自己的范围创建另一个回调。在此代码中,关键字“this”仍然引用原始类。
this.eventButtons = s.eventButtons;
for(b of this.eventButtons){
b.addEventListener('click', () => this.method1);
}
答案 4 :(得分:2)
尝试使用lambda表达式来设置事件的委托。如下所示:
class MainTable extends React.Component {
constructor(props) {
super(props);
this.state = {
results: []
};
}
componentDidMount(){
axios.get(this.props.link)
.then(res => {
this.setState({results: res.data.results});
});
}
render() {
return (
<Table hover striped bordered responsive size="sm">
<thead>
<tr>
<th>Name</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{this.state.results.map(result =>
<tr key={result.fileId}>
<td>{result.Name}</td>
<td>{result.Name}</td>
</tr>
)}
</tbody>
</Table>
);
}
}
答案 5 :(得分: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);
}