2

我尝试用GraphJavaScript 编写一个类,我想将其用作我网站上更多图表的基础。我的问题是mousedown-Handler:

该类的Graph构造函数添加了mousedown-Method:

this.test = "hello world!";
this.svg.on("mousedown", this.mousedown);
// this.svg.on("mousedown", Graph.prototype.mousedown); <-- does the same

而该方法如下所示:

Graph.prototype.mousedown = function() {
    alert(this.test);
};

现在的问题是,这个方法不是在Graph上下文中调用的,而是对g.[object SVGAnimatedString]. 似乎没有Graph.prototype.mousedown调用实际的方法。

有什么办法可以实现我打算在这里做的事情吗?

4

1 回答 1

4

这是 JavaScript 中的一个常见问题,并非 D3 所独有的(您可以在 Google 上搜索“javascript function this object scope”之类的内容以了解更多信息)。特别是在这种情况下,d3 将this对象(也称为上下文)显式设置为与 mousedown 事件关联的 html 或 svg 元素。它在其他几种情况下也做同样的事情,例如在attrandstyle方法内部。这被认为是 d3 的一个有用功能,因为它为您组合了 html 元素及其相关数据。正如您所发现的那样,这确实意味着this当您将类实例方法传递给 d3 方法时存在冲突,这就是为什么您通常不会看到使用这种类构造样式的 d3 示例的部分原因(即利用prototypethis)。

不过,您仍然可以通过将您的this(Graph 的实例)分配给在闭包外部声明的变量来解决它(同样,这是一种通用的 JavaScript 技术,而不是 d3 的东西):

// _this is the instance of your class
_this = this;

// _this inside this closure will continue to point to your Graph instance
this.svg.on("mousedown", function(d, i) { _this.mousedown(d, i) });

请注意,因此,您将无法再从 mousedown 方法中访问关联的 html/svg 元素,如果您不需要它,也可以。否则,您必须将其作为第三个参数传递给您的 mousedown 函数:_this.mousedown(d, i, this).

此外,如果你在很多地方都这样做,这种风格会在一段时间后变得乏味。如果是这样,您可能会考虑切换到以不同的方式定义您的类——而不依赖于prototypethis. 最自然的是,您可能希望按照 d3 对象的实现方式进行操作。您可以通过查看 d3 源代码获得更多信息(寻找d3.svg.axis一个这样的示例)。

于 2013-05-20T21:37:31.723 回答