D3.js:将参数传递给事件处理程序

时间:2017-02-02 23:47:08

标签: angular d3.js typescript event-handling encapsulation

我在Angular 2组件中有一个D3.js代码,用TypeScript编写。

当然,我倾向于以OOP方式包装东西,以便可以(例如)多次重复使用该组件。

但是,我遇到了将事物传递给事件处理程序的问题。

    this.simulation = d3.forceSimulation()
        ...
        .on("tick", this.onSimulationTick);

onSimulationTick()只能访问全局变量d3.eventthis

  

当调度指定的事件时,将使用此上下文作为模拟调用每个侦听器。

全局变量不是一个选项,打破了封装。我无法附加任何内容d3.event,我不知道它们的语境是什么意思。

在处理程序中,我想访问几个类成员的东西。所以最好是传递组件对象。

如何将任何内容传递给处理程序?我如何使用上下文?

也许我可以用某种方式使用lambda,比如

.on("tick", () => onSimulationTick.that = this, onSimulationTick );

这是缩短的组件代码:

@Component({
    templateUrl: "dependencies-graph.component.html",
    styleUrls: ["dependencies-graph.component.css"],
    selector: 'wu-dependencies-graph',
})
export class DependenciesGraphComponent implements OnInit, OnChanges {

    // Data
    _dependencies: DependenciesData;
    private jsonData;

    // Selections
    private zoomingGroup;

    // Behaviors
    private simulation;
    private zoom;
    private center: Point;

    private initVisualisation() {
        this.zoomingGroup = d3.select("svg #zoomingGroup");
        ...
        this.simulation = d3.forceSimulation()
            ...
            .on("tick", this.onSimulationTick);
    }

    static onSimulationTick() {
        ???.zoomingGroup.selectAll(".myEdge")
            .attr("x1", function(item) { return item.source.x; })
            .attr("y1", function(item) { return item.source.y; })
            .attr("x2", function(item) { return item.target.x; })
            .attr("y2", function(item) { return item.target.y; });

        ???.zoomingGroup.selectAll(".myGroup")
                .attr("transform", function(d){return "translate("+d.x+","+d.y+")"});
    }

1 个答案:

答案 0 :(得分:3)

您可以使用Function.prototype.bind方法::

绑定上下文
private initVisualisation() {
    this.zoomingGroup = d3.select("svg #zoomingGroup");
    ...
    this.simulation = d3.forceSimulation()
        ...
        .on("tick", this.onSimulationTick.bind(this));
}

static onSimulationTick() {
    this.zoomingGroup.selectAll(".myEdge")
        .attr("x1", function(item) { return item.source.x; })
        .attr("y1", function(item) { return item.source.y; })
        .attr("x2", function(item) { return item.target.x; })
        .attr("y2", function(item) { return item.target.y; });

    this.zoomingGroup.selectAll(".myGroup")
            .attr("transform", function(d){return "translate("+d.x+","+d.y+")"});
}

如果您想传递其他参数arrow function可能是更好的选择:

.on("tick", () => this.onSimulationTick(somethingElse));