我使用的是最新版本的ember-cli,ember-data,ember-localstorage-adapter和ember。
我有一个Node
对象,其中包含父级和子级。由于我遇到了使用相同类型的对象创建多个关系的问题,因此我决定将parentID存储在字符串中,并将childID存储在字符串数组中。但是,当我创建一个新节点并尝试将新节点添加到父类ID数组时,该ID最终会被添加到正确的父节点,但也会添加到其他父节点。
level 1 0
/ \
level 2 1 2
| |
level 3 3 4
在这样的结构中,0,1和2都具有正确的子ID和父ID。但是,在添加3和4之后,节点1和节点2的子ID分别为[3,4],而不是[3],[4]。
数组属性:
var ArrayTransform = DS.Transform.extend({
serialize: function(value) {
if (!value) {
return [];
}
return value;
},
deserialize: function(value) {
if (!value) {
return [];
}
return value;
}
});
insertNode代码:
insert: function(elem) {
var i,
_store = elem.node.store,
newNodeJSON = elem.node.serialize();
newNodeJSON.childIds = [];
newNodeJSON.level = getNextLevel();
_store.filter('node', function(node) {
return node.get('level') === newnodeJSON.level-1;
}).then(function(prevLevelNodes) {
// if no other nodes yet
if (prevLevelNodes.toArray().length === 0) {
makeNewNode(_store, newNodeJSON, elem.node);
}
// else, generates however many nodes that are in the previous level
else {
prevLevelNodes.toArray().forEach(function(node, idx) {
newNodeJSON.parentId = node.get('id');
makeNewNode(_store, newNodeJSON, elem.node);
});
}
});
}
var makeNewNode = function(_store, newNodeJSON, node) {
console.log(newNodeJSON.parentId); // returns correct value
var newNode = _store.createRecord('node', newNodeJSON);
newNode.save();
var newNodeId = newNode.get('id');
if (newNode.get('parentId')) {
_store.find('node', newNode.get('parentId')).then(function(n) {
var cids = n.get('childIds');
console.log(newNodeId); // returns expected value
console.log(cids); // **DOESN'T RETURN AN EMPTY ARRAY**: returns array with [3,4]
cids.push(newNodeId);
console.log(n.get('childIds')); // returns array with [3,4]
n.save();
});
}
要做到这一点,这个错误会在90%的时间内发生,但会有10%的时间按预期执行。这似乎表明存在某种竞争条件,但我不确定那会是什么。我觉得有些地方可能会导致问题:ember-cli
编译,在制作新节点时传递整个_store
,ember-data
很奇怪,ember-localstorage-adapter
很时髦。 ..没有头绪。
答案 0 :(得分:0)
对于将来可能遇到此问题的其他人:问题在于两件事。
insert
代码中,我将我在函数顶部定义的相同的JSON 传递给makeNewNode
。此JSON包含对单个childIds
数组的引用;因此,每个创建的新节点都会为其childIds使用相同的引用。虽然这并没有解释为什么在执行cids
之前push
数组是空的(也许这是某种编译器的奇怪或控制台打印延迟),但它解释了为什么这些3级孩子都是2级父母和2级孩子。 childIds
数组。
tl; dr:按值传递vs传递参考错误