Meteor:反应性本地采集(仅限客户端)正确观测变化



我有一个包含多个数组的集合,即

memos: [...]
todos: [...]

我将数组中的每个文档插入客户端上的本地集合:

if (Meteor.isClient) {
  this.Memos = new Mongo.Collection(null);
  var results;
  results = Projects.findOne({
    _id: currentProject_id
  });
  results.memos.forEach(function(memo) {
    return Memos.insert(memo);
  });
}

如果我调用一个方法来更改服务器集合中的备忘录:

({
  completeMemo: function(project_id, memo_id, ifCompleted) {
    return Projects.update({
      _id: project_id,
      'memo._id': memo_id
    }, {
      $set: {
        'memos.$.completed': ifCompleted
      }
    });
  }
});

Meteor试图将更改后的文档重新插入本地集合,引发以下错误:

Exception from Tracker recompute function:
MinimongoError: Duplicate _id '43ttergerg33t3t'

与其重新插入文档,我只想反映的更改

我已尝试将return Memos.insert(memo)修改为:

Memos.upsert({
  _id: memo._id
}, {
  $set: {
    direction: memo.direction,
    sender: memo.sender,
    sender_id: memo.sender_id,
    sentAt: memo.sentAt,
    text: memo.text,
    type: memo.type,
    viewed: memo.viewed
  }
});

然而,这会引发同样的错误UPDATE以上操作非常完美,错误来自其他原因。请参阅下面的答案。

如何观察这些文档上的更改并更新已更改的字段

我想我需要以下东西:

Memos = new Mongo.Collection;
query = Projects.findOne({
  _id: currentProject_id
});
handle = query.memos.observeChanges({
  added: function(id, doc) {
    Memos.insert(doc);
  },
  changed: function(id, doc) {
    ..........???;
  },
  removed: function(id) {
    Memos.remove({
      _id: id
    });
  }
});

流星试图将更改后的文档重新插入本地收集

这是正常的,因为你正在插入集合,这里你需要的是对实际文档的更新,对这个使用$set运算符

return Memos.update({_id:memo._id},{$set:{memo:memo}});

点击此处查看有关更新运算符的更多信息

解决方案:

  1. 我将insert更改为upsert,以防止流星尝试插入具有相同_id的新文档
  2. Meteor不允许在客户端上替换整个文档,所以我指定了要更新的字段:

results.memos.forEach(function(memo) {
  return Memos.upsert({
    _id: memo._id
  }, {
    $set: {
      direction: memo.direction,
      sender: memo.sender,
      sender_id: memo.sender_id,
      sentAt: memo.sentAt,
      text: memo.text,
      type: memo.type,
      viewed: memo.viewed
    }
  });
});

最新更新