Я "warp" d3 перетаскиваю код внутри класса и имею проблему с this
когда я пытаюсь использовать поля классов в разных методах класса.
Вот код:
'use strict';
class D3DragHandler {
constructor(link, datas) {
this.drag = null;
this.links = link;
this.datas = datas;
this.zadragged = null;
// console.log(this.link);
}
saveNodePosition() {
var postData = {};
var adragged = this.zadragged; //ERROR HERE
postData.id = datas[adragged].id;
postData.x = datas[adragged].dx + datas[adragged].x;
postData.y = datas[adragged].dy + datas[adragged].y;
d3.xhr('/index.php?option=com_myrod&task=ajax.save&format=json&raw=true&token=' + token + "&data=" + JSON.stringify({
"data": postData
}))
.header("Content-Type", "application/json")
.post("",
function (err, rawData) {
var data = JSON.parse(rawData);
console.log("got response", data);
});
}
setDragged(value) {
console.log(value);
this.zadragged = value; //ERROR HERE
//var v = this.zadragged;
}
init() {
var link = this.links;
var datas = this.datas;
var saveFunc = this.saveNodePosition;
var draggedKeyFunc = this.setDragged;
// Define drag beavior
this.drag = d3.behavior.drag()
.on("drag", function (d) {
var x = d3.event.x;
var y = d3.event.y;
d3.select(this).attr("transform", "translate(" + x + "," + y + ")");
//adragged = d.key;
draggedKeyFunc(d.key);
datas[d.key].dx = d3.event.x;
datas[d.key].dy = d3.event.y;
link.update();
})
.origin(function () {
var t = d3.transform(d3.select(this).attr("transform"));
svg.select("text.position").text(function (d) {
return Math.round(d.value.x) + ":" + Math.round(d.value.y);
})
return {
x: t.translate[0],
y: t.translate[1]
};
})
.on("dragend", function () {
var d = d3.event.sourceEvent;
console.log(d);
saveFunc(d);
});
return this.drag;
}
}
Я комментирую код, чтобы показать, где я получаю ошибки, и это очень странно, потому что я использую this
в других методах, и он работает нормально. Но в этих строках я получаю ошибку:
TypeError: this is undefined
Это очень странно, я ожидаю, что весь код должен работать одинаково, но, может быть, я что-то пропустил?
setDragged(value)
метод класса, поэтому я ожидаю, что this
сам класс.
Ваша проблема заключается в том, что методы класса не привязаны к какому-либо конкретному объекту, поэтому this
относится к любому объекту, который они назывались как метод, поэтому, когда вы это:
var draggedKeyFunc = this.setDragged;
// ...
draggedKeyFunc(d.key);
Эта ассоциация объектов исчезла, и this
не undefined
в строгом режиме или глобальный объект вне строгого режима.
Параметры включают вызов объекта как метода:
var dragHandler = this;
// ...
dragHandler.draggedKeyFunc(d.key);
Или создание связанной функции:
var draggedKeyFunc = this.setDragged.bind(this);
// ...
draggedKeyFunc(d.key);
.bind(this);
, я использую .bind(this);
и все заработало.
Вы можете использовать свойство класса, как показано ниже, если вы включите плагин babel в процессе сборки
setDragged = (value) => {
console.log(value);
this.zadragged = value; //ERROR HERE
}
this
контекст становится глобальным контекстом. Можно назначитьthis
переменной, которая используется внутри другой функции. Просто получите доступ к методу в переменной из другой функции.