[英]Bind with d3 events
在d3中编写事件处理程序时,有没有办法直接使用bind
等价物? 我没有看到在文档中的任何地方实现或讨论bind
。
目前我这样做:
graph = function () {
var self = this;
this.svg = d3.select('body').append('svg');
this.svg.append('svg:rect')
.style('fill', '#f00')
.attr('width', 300)
.attr('height', 300);
this.svg.on('mousedown', function(){return self.mouseDown.call(this, self);})
}
graph.prototype.mouseDown = function (self) {
/* 'self' is the instance of graph */
alert(self.svg);
/* 'this' is the event */
alert(d3.mouse(this));
}
var g = new graph();
这很好用。 然而,使用匿名函数在这里使用call
似乎是不好的做法,因为bind
能够在常规DOM元素上实现这一点(如果我没有使用d3选择)。 我更喜欢使用d3选择而不是针对底层DOM元素(为了保持一致性,因为this.svg
已经附加到graph
对象)。
由于d3的on
方法似乎是分配事件监听器的典型方法 ,所以在这里传递数据还有其他选择吗?
这一切都源于d3依赖于this
关键字指向DOM元素的事实 - 使用this
几乎就像传递给处理函数的另一个参数一样。 这种“冲突”与典型使用this
作为类实例的引用。
由于Function.prototype.bind()
只是一种显式设置函数调用的this
关键字的方法,因此它无法解决您的问题。 换句话说,如果您需要同时访问DOM元素和类实例,则必须设置一个像self
这样的辅助变量来指向这两个中的一个。
那得是至少部分原因D3自己的类(如d3.svg.axis
)不使用prototype
类声明的方式,而不是依赖于关闭(如描述在这里 )。 因此,要么切换到该类声明的样式,要么必须按照您在示例中显示的方式继续进行。 你的例子中也有这个更惯用的变体,但它仍然与你拥有的基本相同:
graph = function () {
this.svg = d3.select('body').append('svg');
this.svg.on('mousedown', this.mouseDownHandler())
}
graph.prototype.mouseDownHandler = function () {
/* 'self' is the instance of graph */
var self = this;
return function(d, i) {
/* 'this' is the DOM element */
alert(d3.mouse(this));
/* now you can work with both "self" and "this" */
}
}
var g = new graph();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.