如何在 React / Backbone 环境中删除 JSPlumb-Element?
How to delete a JSPlumb-Element in a React / Backbone environment?
我有一个 backbonejs 模型集合,其中包含 JSPlumb 节点(ID、parentID)的模型。 DOM 表示由 React 处理(带有端点的 div)。如果我从集合中删除模型:
nodeCollection.remove(aNodeModel)
它连同所有包含的组件一起从 DOM 中删除 - 很好。
如果我现在添加一个新节点,则不会添加端点。我将此问题追溯到 JSPlumb 中的一些内部结构:如果我执行
jsPlumb.remove(aNodeModel.id)
端点问题消失了,但我得到了一个 React "Invariant Violation",因为 aNodeModel
没有从 nodeCollection 中删除。
如果我在从集合中删除模型之前手动删除 jsPlumb 端点:
jsPlumb.removeAllEndpoints(aNodeModel.id)
问题依旧。
这感觉有点像死锁...有什么建议吗?
开源 roxx。
我通过向 jsPlumb .remove() 方法添加一个参数来控制 jsPlumb 中元素的实际 DOM 删除来解决这个问题。如果我将其设置为 false jsPlumb 得到很好的清理,我可以让 React 删除实际的 DOM-element 之后:
jsPlumb.remove(sourceNodeID, false, [false])
这是我在 dom.jsPlumb-1.7.5.js 第 5176 和 5210 行中对 jsPlumb 源所做的更改。
var _doRemove = function(info, affectedElements, removeDOMElement) {
_currentInstance.removeAllEndpoints(info.id, true, affectedElements);
var _one = function(_info) {
_currentInstance.getDragManager().elementRemoved(_info.id);
_currentInstance.anchorManager.clearFor(_info.id);
_currentInstance.anchorManager.removeFloatingConnection(_info.id);
delete _currentInstance.floatingConnections[_info.id];
delete managedElements[_info.id];
delete offsets[_info.id];
var actuallyRemoveDOMElement = true;
if (removeDOMElement.length > 0) {
actuallyRemoveDOMElement = removeDOMElement[0];
}
if (_info.el) {
if (actuallyRemoveDOMElement) {
_currentInstance.removeElement(_info.el);
}
_info.el._jsPlumb = null;
}
};
// remove all affected child elements
for (var ae = 1; ae < affectedElements.length; ae++) {
_one(affectedElements[ae]);
}
// and always remove the requested one from the dom.
_one(info);
};
/**
* Remove the given element, including cleaning up all endpoints registered for it.
* This is exposed in the public API but also used internally by jsPlumb when removing the
* element associated with a connection drag.
*/
this.remove = function (el, doNotRepaint, removeDOMElement) {
var info = _info(el), affectedElements = [];
if (info.text) {
info.el.parentNode.removeChild(info.el);
}
else if (info.id) {
_currentInstance.batch(function () {
_doRemove(info, affectedElements, removeDOMElement);
}, doNotRepaint === false);
}
return _currentInstance;
};
我有一个 backbonejs 模型集合,其中包含 JSPlumb 节点(ID、parentID)的模型。 DOM 表示由 React 处理(带有端点的 div)。如果我从集合中删除模型:
nodeCollection.remove(aNodeModel)
它连同所有包含的组件一起从 DOM 中删除 - 很好。
如果我现在添加一个新节点,则不会添加端点。我将此问题追溯到 JSPlumb 中的一些内部结构:如果我执行
jsPlumb.remove(aNodeModel.id)
端点问题消失了,但我得到了一个 React "Invariant Violation",因为 aNodeModel
没有从 nodeCollection 中删除。
如果我在从集合中删除模型之前手动删除 jsPlumb 端点:
jsPlumb.removeAllEndpoints(aNodeModel.id)
问题依旧。
这感觉有点像死锁...有什么建议吗?
开源 roxx。
我通过向 jsPlumb .remove() 方法添加一个参数来控制 jsPlumb 中元素的实际 DOM 删除来解决这个问题。如果我将其设置为 false jsPlumb 得到很好的清理,我可以让 React 删除实际的 DOM-element 之后:
jsPlumb.remove(sourceNodeID, false, [false])
这是我在 dom.jsPlumb-1.7.5.js 第 5176 和 5210 行中对 jsPlumb 源所做的更改。
var _doRemove = function(info, affectedElements, removeDOMElement) {
_currentInstance.removeAllEndpoints(info.id, true, affectedElements);
var _one = function(_info) {
_currentInstance.getDragManager().elementRemoved(_info.id);
_currentInstance.anchorManager.clearFor(_info.id);
_currentInstance.anchorManager.removeFloatingConnection(_info.id);
delete _currentInstance.floatingConnections[_info.id];
delete managedElements[_info.id];
delete offsets[_info.id];
var actuallyRemoveDOMElement = true;
if (removeDOMElement.length > 0) {
actuallyRemoveDOMElement = removeDOMElement[0];
}
if (_info.el) {
if (actuallyRemoveDOMElement) {
_currentInstance.removeElement(_info.el);
}
_info.el._jsPlumb = null;
}
};
// remove all affected child elements
for (var ae = 1; ae < affectedElements.length; ae++) {
_one(affectedElements[ae]);
}
// and always remove the requested one from the dom.
_one(info);
};
/**
* Remove the given element, including cleaning up all endpoints registered for it.
* This is exposed in the public API but also used internally by jsPlumb when removing the
* element associated with a connection drag.
*/
this.remove = function (el, doNotRepaint, removeDOMElement) {
var info = _info(el), affectedElements = [];
if (info.text) {
info.el.parentNode.removeChild(info.el);
}
else if (info.id) {
_currentInstance.batch(function () {
_doRemove(info, affectedElements, removeDOMElement);
}, doNotRepaint === false);
}
return _currentInstance;
};