2017-02-02 98 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,所以不知道這是否會工作。也試試 –

相關問題