Typescript / D3 v4 - d3.drag()中的上下文。(“end”,this.dragended)

时间:2016-08-14 18:28:12

标签: d3.js typescript d3.js-v4

我正在使用D3库来移动维恩图中的项目。当我停止拖动时,我想确定图表中项目的位置。

item.call(d3.drag()
    .on("start", this.dragstarted)
    .on("drag", this.dragged)
    .on("end", this.dragended)
);

这些是我在拖动开始时调用的函数,正在进行和结束。

dragended(d: TCMemberScenario, i: number) {
    d3.select(this).classed("active", false);
    d.calculateRoles();
    this.save();
}

这是拖动结束时调用的函数。我更新了图中的一些内容,然后我想调用save方法。这是班上的另一种方法。但是,此变量引用D3对象而不是类的实例。 所以我得到一个“未捕获的TypeError:无法读取未定义的属性'保存”

如何从dragended方法中调用我班级的另一种方法?

2 个答案:

答案 0 :(得分:2)

如果您需要保持对类实例的引用以及d3拖动引用的元素实例,您可以将侦听器函数定义为:

export class MyClass {
    @Input()
    radius: number = 45;

    constructor() {
        d3.drag()
          .on("start", this.dragStarted(this))
          .on("drag", this.dragged(this))
          .on("end", this.dragEnded(this));
    }

    private dragged(self) {
        return function(d) {
            // 'this' in this context will be the d3 element

            d3.select(this)
              .attr("cx", d.x = self.radius * Math.cos(alpha))
              .attr("cy", d.y = d3.event.y < 0 ? -self.radius * Math.sin(alpha) : self.radius * Math.sin(alpha));
        }
    }

    ...

}

使用d3.js v4进行测试

答案 1 :(得分:0)

原则上,D3将选择,转换等回调的this上下文绑定到它们运行的​​DOM元素。

通过暗示,如果您需要在词法范围意义上访问“包装对象”的this上下文,则不能使用this来访问它。适用于您的具体案例:

  • d3.select(this)将对当前迭代的DOM元素进行操作,该元素将具有item选择的DOM元素类型。因此,如果您的item是例如类型为SVGCircleElement,这将是this函数的dragended上下文。
  • 访问包装对象this上下文的一种方法是在dragended函数周围创建一个闭包:

您可以向包含对象添加私有方法,该方法具有save方法:

private getDragEndedHandler() {
  let self = this; // object context to preserve
  return function(d: TCMemberScenario, i: number) {
    d3.select(this).classed("active", false); // D3 bound DOM element context
    d.calculateRoles();
    self.save(); // closure-preserved object context
  }
}

现在,当您绑定处理程序事件时,您只需执行以下操作:

item.call(d3.drag()
    .on("start", this.dragstarted)
    .on("drag", this.dragged)
    .on("end", this.getDragEndedHandler())
);

如果需要,可以将相同的模式应用于其他事件处理程序。

如果你使用来自npm @types的d3-selectiond3-drag的最新定义,你会发现他们现在有了泛型来更明确地说明与DOM有关的this上下文类型元素和D3回调。