mxgraph бесконечные циклы при применении

Я расширяю элемент управления удалением mxgraph пример, чтобы добавить элементы управления удалением в узлы которые генерируются динамически на моем графике. Исходный код примера доступен здесь

Проблема в этой части кода -

            // Overridden to add an additional control to the state at creation time
            mxCellRendererCreateControl = mxCellRenderer.prototype.createControl;
            mxCellRenderer.prototype.createControl = function(state)
            {
                mxCellRendererCreateControl.apply(this, arguments);

                var graph = state.view.graph;

                if (graph.getModel().isVertex(state.cell))
                {
                    if (state.deleteControl == null)

mxCellRendererCreateControl.apply внутри переопределенного обратного вызова createControl, по-видимому, работает должным образом (вызывает исходную функцию перед созданием дополнительных элементов управления) с начальным состоянием графа при загрузке. Но как только я динамически добавляю узлы в граф и обратный вызов вызывается с помощью проверки/перерисовки mxgraph, управление переходит в бесконечный цикл, где функция «применить» в основном продолжает вызывать себя (т. е. обратный вызов).

Я немного не в курсе, потому что при отладке контекст (это) выглядит нормально, но я не могу понять, почему вместо вызова метода прототипа он просто продолжает вызывать переопределенную функцию в цикле. Что я делаю не так?


person Jay    schedule 26.09.2017    source источник
comment
Можете ли вы уточнить, что такое mxCellRendererCreateControl и почему вы переопределяете и используете prototype?   -  person Ghassen Louhaichi    schedule 28.09.2017
comment
Можно ли создать минимальный онлайн-пример?   -  person Sotiris Kiritsis    schedule 28.09.2017
comment
@GhassenLouhaichi mxCellRendererCreateControl — это метод createControl в mxCellRenderer.js. Вы можете увидеть его источник здесь — github .com/jgraph/mxgraph/blob/master/javascript/src/js/view/, строка 600. Он создает базовый прямоугольник/форму, которую вы хотите отобразить, прежде чем рисовать поверх фигуры и добавлять элемент управления удалением. Что касается того, почему я переопределяю это, это просто рекомендуемый способ сделать это в mxgraph. Вы можете увидеть это в первой ссылке примера, опубликованной в этом посте. Вы можете видеть значки удаления поверх узлов. Они рисуются переопределением.   -  person Jay    schedule 28.09.2017
comment
Понятно, а как вы динамически добавляете узлы?   -  person Ghassen Louhaichi    schedule 28.09.2017
comment
@GhassenLouhaichi просто стандартный метод addCell в mxgraph. Информация, связанная с узлом, извлекается из базы данных. Я пытаюсь создать онлайн-пример, который воспроизвел бы эту проблему без db. Вы видите какую-либо проблему в коде, который я вставил выше? Почему функция применения ведет себя иначе на втором проходе (т. е. когда добавляются узлы и обновляется граф), но отлично работает на первом проходе.   -  person Jay    schedule 28.09.2017
comment
Хорошо, я добавил предложение, пожалуйста, попробуйте и дайте мне знать.   -  person Ghassen Louhaichi    schedule 28.09.2017
comment
@GhassenLouhaichi спасибо, попробую.   -  person Jay    schedule 28.09.2017
comment
Удачи с исправлением?   -  person Ghassen Louhaichi    schedule 28.09.2017
comment
@Jay, можешь обновить вопрос, включив в него код для добавления ящиков?   -  person TheChetan    schedule 04.10.2017


Ответы (2)


Похоже, вы неправильно клонируете исходную функцию, попробуйте следующее:

Function.prototype.clone = function() {
    var that = this;
    return function theClone() {
        return that.apply(this, arguments);
    };
};

Добавьте этот новый метод где-нибудь в свой основной код, чтобы он был доступен во всем приложении, теперь вы можете изменить свой код на:

// Overridden to add an additional control to the state at creation time
let mxCellRendererCreateControl = mxCellRenderer.prototype.createControl.clone();
mxCellRenderer.prototype.createControl = function(state) {
    mxCellRendererCreateControl(state);

    var graph = state.view.graph;
    if (graph.getModel().isVertex(state.cell)) {
        if (state.deleteControl == null) {
            // ...
        }
    }
    // ...
};

Это должно работать, если я правильно понял вашу проблему, если это не так, измените старый вызов функции обратно на apply. В противном случае дайте мне знать, если после изменения прототипа Function произойдет что-то другое.

person Ghassen Louhaichi    schedule 28.09.2017
comment
Спасибо за ответ. Я пробовал, но это не решило проблему. - person Jay; 28.09.2017
comment
Что-нибудь изменилось? Или то же самое произошло? - person Ghassen Louhaichi; 28.09.2017
comment
Ничего не изменилось. такой же результат. - person Jay; 28.09.2017
comment
Не могли бы вы добавить код добавления своей ячейки? Может быть, мы сможем увидеть что-то там. - person Ghassen Louhaichi; 29.09.2017
comment
Пытаюсь получить код - скоро добавлю. Мне нужно избавиться от вызовов БД и добавить несколько фиктивных вызовов. Как только это будет сделано, я добавлю код. - person Jay; 29.09.2017

Кажется, что ваш переопределяющий код вызывается несколько раз (для проверки этого достаточно добавить простой console.log перед вашим переопределяющим кодом)

Постарайтесь убедиться, что код, переопределяющий функцию, вызывается только один раз, или проверьте, является ли функция-прототип оригинальной или вашей.

Вот пример того, как вы можете проверить, ваша функция или нет

if (!mxCellRenderer.prototype.createControl.isOverridenByMe) {
    let mxCellRendererCreateControl = mxCellRenderer.prototype.createControl;
    mxCellRenderer.prototype.createControl = function(state) { /* ... */ };
    mxCellRenderer.prototype.createControl.isOverridenByMe = true;
}

Есть и другие способы, например использование глобальной переменной для проверки того, переопределили ли вы метод или нет.

Если это не решит вашу проблему, пожалуйста, опубликуйте больше об остальной части вашего кода (как этот код загружается/вызывается, очень поможет)

person Tiago Sousa    schedule 03.10.2017
comment
Спасибо, что нашли время ответить на этот вопрос. Ценю вашу помощь. - person Jay; 03.10.2017