应用时 mxgraph 无限循环

mxgraph infinite loops on apply

我正在扩展 mxgraph 删除控件example to add delete like controls to nodes which are generated dynamically in my graph. The source code for the example is available here

问题出在这部分代码 -

            // 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 的 validate/redraw 调用,控件就会进入无限循环,其中 'apply' 函数基本上会继续调用自身(即回调)。

我有点懵,因为我调试的时候,context(this) 看起来很好,但是我想不通为什么不调用原型方法,而是一直循环调用被覆盖的函数。我究竟做错了什么?

您似乎没有以正确的方式克隆原始函数,请尝试以下操作:

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 原型更改后发生了不同的事情,请告诉我。

您的覆盖代码似乎被多次调用(在您的覆盖代码之前添加一个简单的 console.log 应该足以测试它)

尽量确保覆盖函数的代码只被调用一次,或者验证原型函数是原始函数还是你的。

这是一个示例,说明如何检查函数是否属于您

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

还有其他方法,比如使用全局变量来检查您是否重写了该方法。

如果这不能解决您的问题,请post更多地了解您的代码的其余部分(这段代码如何loaded/called会有很大帮助)