2017-02-02 5 views
1

TypeScript로 작성된 Angular 2 구성 요소 내에 D3.js 코드가 있습니다.D3.js : 이벤트 처리기에 매개 변수 전달

필자는 당연히 OOP 방식으로 항목을 래핑하는 경향이 있으므로 구성 요소를 여러 번 다시 사용할 수 있습니다.

그러나 이벤트 처리기에 전달하는 것과 관련하여 문제가 있습니다. 지정된 이벤트가 전달되면

, 각 리스너가 시뮬레이션으로 이러한 맥락으로 호출됩니다

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

onSimulationTick() 전역 변수, d3.eventthis 만 액세스 할 수 있습니다.

전역 변수는 옵션이 아니며 캡슐화를 중단합니다. d3.event에 아무 것도 첨부 할 수 없으며 컨텍스트가 의미하는 바를 모르겠습니다.

핸들러에서 클래스 멤버 인 몇 가지 항목에 액세스하려고합니다. 그래서 최고의 구성 요소 개체를 전달하는 것입니다.

처리기에 무엇을 전달할 수 있습니까? 컨텍스트를 어떻게 사용할 수 있습니까?

@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+")"}); 
} 

와 컨텍스트를 결합 수 :

은 어쩌면 내가 여기

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

단축 구성 요소 코드처럼, 어떤 방법으로 람다를 사용할 수 있습니다 추가 매개 변수를 전달하려는 경우 arrow function이 더 나은 옵션 일 수 있습니다.

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

하! 나는 bind()에 대해 완전히 잊었다. 시도하려고합니다. –

+0

lambda를 사용하면 ES5로 컴파일되므로 제대로 작동하는지 확실하지 않습니다. 시도해 보러 간다. –