JavaScript `this` работает по-разному в разных методах класса

1

Я "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 сам класс.

  • 1
    Когда вы назначаете функции переменным, this контекст становится глобальным контекстом. Можно назначить this переменной, которая используется внутри другой функции. Просто получите доступ к методу в переменной из другой функции.
Теги:
class
d3.js
this

2 ответа

4
Лучший ответ

Ваша проблема заключается в том, что методы класса не привязаны к какому-либо конкретному объекту, поэтому 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);
  • 0
    Спасибо, Александр, теперь я .bind(this); , я использую .bind(this); и все заработало.
1

Вы можете использовать свойство класса, как показано ниже, если вы включите плагин babel в процессе сборки

setDragged = (value) => {
    console.log(value);
    this.zadragged = value; //ERROR HERE
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню