2015-10-01 14 views
14

Ist das möglich? Ich bin mir nicht sicher, da d3 macht stark Gebrauch von this Rebindings und dies scheint mit ES6 spec zu widersprechen.Verwenden von Pfeilfunktionen mit d3

Zum Beispiel funktioniert die folgende fein:

// Working fine 
var data = [1,2,3] 
var svg = d3.select('body').append('svg').attr('height', 500).attr('width', 500).style('background-color', 'orange'); 
var gs = svg.selectAll('g').data(data).enter(); 
gs.append('circle') 
    .attr('cx', function() { return Math.random()*500; }) 
    .attr('cy', function() { return Math.random()*500; }) 
    .attr('r', function() { return Math.random()*100; }) 
    .each(function() { console.log(this); }); // this is bound to the current element in the enter selection 

Während die folgende funktioniert nicht wie erwartet (this ist nicht auf das aktuelle Element in der Auswahl eingeben gebunden, sondern an Window Objekt):

var data = [1,2,3] 
var svg = d3.select('body').append('svg').attr('height', 500).attr('width', 500).style('background-color', 'blue'); 
var gs = svg.selectAll('g').data(data).enter(); 
gs.append('circle') 
    .attr('cx',() => Math.random()*500) 
    .attr('cy',() => Math.random()*500) 
    .attr('r',() => Math.random()*100) 
    .each(() => console.log(this)); // this is bound to Window object 

Verwandte Geige here.

+1

@chriskelly Ihr Beispiel einfach den gleichen Wert für alle Elemente in der Auswahl legt, was das ist nicht, dass ich erreichen will (Deshalb werden die Funktionen pro Element verwendet. – jarandaf

+1

Wenn ich Ihr Beispiel ausführe, sehe ich nur das Protokoll der Ausgabekonsole. Aber warum willst du auf '' 'this''' zugreifen? Das ist eine interessante Frage, aber ich würde gerne einen Fall wissen, in dem es ein Problem wäre. – chriskelly

+0

@chriskelly es ist ein ziemlich konkreter Anwendungsfall (habe eine Funktion, die ich wiederverwenden möchte, die eine komplexe Struktur von Elementen innerhalb der Svg-Gruppe erzeugt, ich brauche 'this' um zu wissen, auf welche Gruppe ich referenziere, wo neue Elemente angehängt werden). – jarandaf

Antwort

8

Sie können Pfeilfunktionen verwenden, wenn Sie keinen Zugriff auf this des aktuellen Elements benötigen.

Fallback zu den alten Stilfunktionen für Fälle, in denen Sie auf this des aktuellen Elements zugreifen möchten.

Oder verwenden Sie explizite Bindung an Ihre Funktion (nicht Pfeil-Funktion) für den Zugriff zu erlauben, was Objekt, das Sie .bind()

mit wollen mit this arbeiten Um zu vermeiden, haben Sie die Möglichkeit, d3 Namen oder Klasse Selektoren bequem Zugang jedes Element. Beispiel:

var stuffINeed = svg.selectAll('.someClass'); 
2

Es ist nicht möglich, das Verhalten einer Pfeilfunktion zu ändern. Ihre Bindung ist "fest codiert" und kann nicht durch erneutes Binden mit der bind-Methode oder durch Aufrufen einer anderen Funktionsmethode, die einen expliziten Ausführungskontext akzeptiert (z. B. apply), geändert werden. Das gleiche gilt für jede gebundene Funktion - einmal gebunden, wird die zurückgegebene Funktion gebunden für immer.

Ist es möglich?

Mit dem oben im Kopf, wenn d3 bind ing verwendet bequeme Verkettung Verhalten zu schaffen, kann diese nicht mit Pfeilfunktionen erreicht werden, bis API d3 in irgendeiner Weise modifiziert wird, um sie unterzubringen.

5

Wenn Sie d3v4 verwenden, können Sie den aktuellen DOM-Knoten wie folgt zugreifen:

gs.append('circle') 
    .attr('cx',() => Math.random()*500) 
    .attr('cy',() => Math.random()*500) 
    .attr('r',() => Math.random()*100) 
    .each((d, i, j) => console.log(j[i])); 
     // j is current group, i is current index 
Verwandte Themen