函数内更新类属性问题:点击事件中this指向不符预期
解决D3点击事件中类实例
this指向问题 这个问题我太熟了——在D3的事件处理函数里,用传统function()定义的回调会把this绑定到被点击的DOM元素(也就是你代码里的<rect>元素),而不是你的Chart类实例,所以你直接赋值this.bar = d根本找不到类里的bar属性。给你三个实用的解决办法:
1. 用ES6箭头函数(最推荐)
箭头函数不会创建自己的this上下文,它会继承外层作用域的this,也就是你的Chart类实例。这样你就能直接在回调里访问类的bar属性了:
export class Chart { constructor() { this.bar; } showChart() { // ... 你的其他代码 let group = svg.selectAll('g').data(data).enter().append('g'); group.append('rect') .on('click', (d) => { // 这里的this就是Chart类的实例了! this.bar = d; }); } }
⚠️ 注意:如果之后你需要访问被点击的DOM元素,箭头函数里不能用this,得用d3.event.currentTarget来获取。
2. 提前保存类实例的this到变量
如果你的环境还不支持ES6箭头函数,可以在showChart方法开头先把类实例的this存到一个变量(比如self或者that),然后在回调里用这个变量访问类属性:
export class Chart { constructor() { this.bar; } showChart() { // 先把类实例的this存下来 const self = this; // ... 你的其他代码 let group = svg.selectAll('g').data(data).enter().append('g'); group.append('rect') .on('click', function(d) { // 用self代替this,指向Chart类实例 self.bar = d; // 这里的this还是被点击的rect元素,需要的话可以正常用 }); } }
3. 用bind()绑定this
你也可以通过bind()方法把回调函数的this强制绑定到类实例上:
export class Chart { constructor() { this.bar; } showChart() { // ... 你的其他代码 let group = svg.selectAll('g').data(data).enter().append('g'); group.append('rect') .on('click', function(d) { this.bar = d; }.bind(this)); // 把this绑定到Chart类实例 } }
这种方法和箭头函数的效果类似,但需要手动调用bind,代码稍微啰嗦一点。
内容的提问来源于stack exchange,提问作者isar
相关产品推荐
相关产品推荐

