Мне нужна помощь в понимании того, что происходит в моем маленьком коде. В моем веб-приложении я использую D3. js для рисования фигур, которые я называю маркерами . Маркер можно перетаскивать по экрану, и при каждом перетаскивании я беру его позицию, делаю некоторые вычисления и обновляю объект данных, назначенный этому маркеру. Позвольте мне показать вам:
class Marker {
constructor(name) {
this.name = name;
this.computedStuff = 0;
}
getDisplayName() {
return 'Marker ' + this.name;
}
}
this.markerValues = {
'm1': new Marker('m1'),
'm2': new Marker('m2')
}
this.svg.selectAll('g.marker')
.data(_.values(this.markerValues))
.join(enter => {
const group = enter.append('g');
group.append('path')
.attr('d', 'M -12.867771,6.1070093 V 13.761566 H 12.867771 '
+ 'V 6.1070093 H 6.4338855 '
+ 'L 0,-1.1321257 -6.4338856,6.1070093 Z')
.attr('transform', `translate(0 120) scale(2)`)
.attr('stroke', 'black')
.attr('stroke-width', '1px')
.attr('fill', '#fff')
.on('dblclick', d => console.log(d));
group.append('text')
.attr('y', 120)
.text(d => d.getDisplayName())
.style('font-size', '10px')
.style('fill', 'black');
return group;
})
.attr('class', 'marker')
.call(d3.drag()
.on('drag', function (d) {
// Computation here
d.computedStuff = computedAbove;
// Here is a typical code for moving a marker according to
// d3.event.
})
);
Проблема заключается в следующем: .on('dblclick', d => console.log(d));
. Это выглядит довольно просто - при двойном щелчке зарегистрируйте содержимое данных; и это "работает" хорошо, пока я не переместу маркер. Когда маркер перемещается, переменная computedStuff
изменяется из-за вычислений, но последующие двойные щелчки по пути записывают старое значение в консоли, как будто объект вообще не изменялся. Я на 100% уверен, что он изменился, потому что я проверил содержимое объекта this.markerValues
. Выглядит так, как будто к обработчику событий была прикреплена копия объекта, и он записывает копию вместо исходного объекта.
Но ...
Когда я удаляю этот обработчик событий из пути и присоедините его к группе: group.on('dblclick', d => console.log(d));
, тогда это работает! Я могу переместить маркер, дважды щелкнуть его, и мне всегда будет предоставлено правильное значение.
Почему обработчику группы всегда предоставляются действительные данные, тогда как обработчик, прикрепленный к дочернему элементу группы, сохраняет какой-то вид копии или объекта, на который нет ссылок?