2017-02-02 12 views
1

TypeScriptで書かれたAngular 2コンポーネント内にD3.jsコードがあります。D3.js:イベントハンドラにパラメータを渡す

もちろん、私は物事をOOPの方法でラップする傾向があります。そのため、コンポーネントは(複数の)再利用できるようになります。

しかし、イベントハンドラに何かを渡すことに問題があります。

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

Ha!私は 'bind()'を完全に忘れてしまった。試しに行く。 –

+0

ラムダでは、ES5にコンパイルするので、それが動作するかどうかはわかりません。試しに行く –

関連する問題