【发布时间】:2019-05-19 05:30:18
【问题描述】:
我有一个包装 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 已绑定到提供给 on 的回调(第 3 行)。还要注意使用function 而非(...) => { ... }——以允许D3 将this 绑定到它需要的对象。
如果我可以通过其他方式访问我在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)
})
})
}
【问题讨论】:
-
_links和_nodes的类型是什么?如果您的类型是正确的(您的和库定义都是正确的),那么简单函数中的this应该是正确的类型。您可以为this(function (this: any, other params)) 添加显式注释,但我建议您调试为什么编译器无法确定this是谁 -
@TitianCernicova-Dragomir _links 和 _nodes 分别是
d3.select(document.body).select('.node')和.select('.link')返回的值。其中那些分别指的是带有“.nodes”和“.link”类的html元素。 -
如果我在类中的 this._nodes 和 _links 声明中指定一个“选择”类型,我会遇到其他错误,例如选择类型上不存在
selectAll。我使用 Selection 是因为它看起来像它返回的内容,但我可能弄错了 (github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/d3/…) -
作为
this的替代方案,您可以使用侦听器函数的第二个和第三个参数:function(d,i,g) { d3.select(g[i])...,相当于function() { d3.select(this)...。 (g是选择中的元素 - 请参阅selection.on下的文档 here) -
@AndrewReid 这就是我真正想要的。当我阅读文档时,我一定忽略了文档中的那一点细节。谢谢。让我试一试。
标签: javascript typescript d3.js