Использование функций стрелок с 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 каким-либо образом не будет изменен для их размещения.