Использование функций стрелок с d3

Возможно ли это? Я не уверен, поскольку d3 активно использует перекодировки this, и это, похоже, противоречит ES6 spec.

Например, следующее прекрасно работает:

// 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

В то время как следующее не работает должным образом (this не привязан к текущему элементу в элементе ввода, а в объекте Window):

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

Связанный скрипт здесь.

Ответы

Ответ 1

Вы можете использовать функции стрелок, если вам не нужен доступ к this текущего элемента.

Возврат к старым функциям стиля для случаев, когда вы хотите получить доступ к this текущего элемента.

Или используйте явное привязку, чтобы ваша функция (не функция стрелки) позволяла вам получить доступ к любому объекту, который вы хотите использовать .bind()

Чтобы избежать работы с this, вы можете использовать имя d3 или селектор классов для удобного доступа к любому элементу. например:.

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

Ответ 2

Если вы используете d3v4, вы можете получить доступ к текущему DOM node следующим образом:

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

Ответ 3

Невозможно изменить поведение функции стрелки. Их привязка "жестко закодирована" и не может быть изменена путем повторного связывания с методом bind или вызовом любого другого метода Function, который принимает явный контекст выполнения (например, apply). То же самое можно сказать и о любой связанной функции - однажды связанной, возвращаемая функция привязана навсегда.

Возможно ли это?

С учетом вышеизложенного, если d3 использует bind ing для обеспечения удобного поведения цепочки, этот не может быть достигнут, используя функции стрелок до тех пор, пока API d3 каким-либо образом не будет изменен для их размещения.