2017-02-02 139 views
1

我在用TypeScript编写的Angular 2组件中有一个D3.js代码。当然,我倾向于用OOP的方式来包装东西,以便组件可以(例如)多次重复使用。D3.js:将参数传递给事件处理函数

但是,我有一个问题传递给事件处理程序。

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

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

如果调度了指定的事件,每个监听器将与这一背景下作为模拟调用。

全局变量不是一个选项,打破封装。我无法附加任何内容到d3.event,我不知道它们的含义。

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

我该如何传递任何东西给处理程序?我怎样才能使用它的上下文?

也许我可以以某种方式使用拉姆达,像

.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

您能结合上下文中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)); 
+0

哈!我完全忘了bind()。去尝试。 –

+0

随着lambda,我们编译为ES5,所以不知道这是否会工作。也试试 –

相关问题