灰烬商店添加属性不正确



我使用的是ember-cli、ember-data、ember-localstorage-adapter和ember的最新版本。

我有一个Node对象,它有父对象和子对象。由于我在使用相同类型的对象创建多个关系时遇到了问题,所以我决定将parentID存储在字符串中,而将childid存储在字符串数组中。但是,当我创建一个新Node并尝试将新Node添加到父ID数组时,ID最终被添加到正确的父,但也添加到其他父。

level 1      0
            / 
level 2    1   2
           |   |
level 3    3   4

在这样的结构中,0、1和2都有正确的子id和父id。但是,添加3和4后,节点1和节点2的childid分别为[3,4],而不是[3],[4]。

Array属性:

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很时髦……没有线索。

对于将来可能遇到这种问题的任何人:问题在于两件事。

  • 在ArrayTransform中,通常我返回无修改的值。
  • 在我的insert代码中,我正在传递相同的JSON,我在函数顶部定义了makeNewNode

这个JSON包含一个对单个childIds数组的引用;因此,创建的每个新节点对其子节点使用相同的引用。虽然这并不能完全解释为什么cids数组在push执行之前不是空的(也许这是某种编译器的奇怪或控制台打印延迟),但它解释了为什么这两个3级子程序都在两个2级父程序的childIds数组中。

tl;dr: pass by value vs pass by reference error

最新更新