我有一个包装 D3 的类。我正在将其转换为 TypeScript,但遇到以下两个错误,并且不知道如何修复它们(实际上有多个错误,但它们都与这一对类似),
src/d3-graph.ts:295:19 - error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
295 d3.select(this)
~~~~
src/d3-graph.ts:294:23
294 .on('mouseout', function(d: any) {
~~~~~~~~
An outer value of 'this' is shadowed by this container.
代码(类内的方法,添加行号以供引用),
...
1 private _enableNodeHighlightOnHover() {
2 this._nodes
3 .on('mouseout', function(d: any) {
4 d3.select(this)
5 .style('stroke-width', '2px')
6 })
7 }
...
注意第 2 行,this
指的是该类的实例对象。
在第 4 行,this
引用了对象 D3,该对象已绑定(bind)到提供给 on
(第 3 行)的回调函数上。另请注意在 (...) => { ... }
上使用 function
——以允许 D3 将 this
绑定(bind)到它需要的对象。
如果我可以访问在 d3.select(this)
中使用的 D3 对象,我非常乐意在回调函数中失去 this
用法以其他方式。但我不确定那会是什么。
还需要适应此模式的其他用途,
private _enableDrag() {
const that = this
this._drag = d3.drag()
this._drag
.on('drag', function(d: any) {
d.x += d3.event.dx
d.y += d3.event.dy
d3.select(this)
.attr('cx', d.x)
.attr('cy', d.y)
that._links.each(function(l: any) {
if (l.source === d.id)
d3.select(this)
.attr('x1', d.x)
.attr('y1', d.y)
else if (l.target === d.id)
d3.select(this)
.attr('x2', d.x)
.attr('y2', d.y)
})
if (that._nodeTextLabels === null)
logger.warn(
'enableDrag called before this._nodeTextLabels has been initialized')
else
that._nodeTextLabels.each(function(n: any) {
if (n.id == d.id)
d3.select(this)
.attr('x', d.x + D3Graph._LABEL_FONT_SIZE / 2)
.attr('y', d.y + 15)
})
that._nodes.each(function(n: any) {
if (n.id == d.id)
d3.select(this).select('circle')
.attr('cx', d.x)
.attr('cy', d.y)
})
})
}
最佳答案
作为 this
的替代方案,尝试使用监听器函数的第二个和第三个参数:
function(d,i,group) { d3.select(group[i] ... })
这是有效的,因为当使用 selection.on("event",function(){})
或 selection.each(function() {})
时,d3 绑定(bind)所提供函数的当前元素到 this
。 D3 还将三个参数绑定(bind)到提供的函数:
- 当前数据 (
d
) - 当前索引 (
i
) - 选择中的元素组,而不是选择的元素(此处名为
组
)
使用时:
selection.on("event", function() { d3.select(this); })
您实际上正在做同样的事情:
selection.on("event", function(d,i,group) { d3.select(group[i]); })
由于 group
保存选择的元素,并且 i
是当前索引,因此 group[i]
是当前元素,即与this
相同。
使用group[i]
允许使用箭头函数和环境,这些函数和环境可能会改变this
的上下文,同时仍然访问当前元素。
关于javascript - D3回调函数的 `this`阴影对象的 `this`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53839100/