流星:反应性本地集合(仅限客户端)正确的 observeChanges

Meteor: reactive local collection (client-only) correct observeChanges

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

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
    });
  }
});

meteor tries to re-insert the changed document into the local collection

这是正常的,因为您要插入到集合中,这里您需要更新实际文档,为此使用$set 运算符

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

查看有关更新运算符的更多信息here

解决方案:

  1. 我将 insert 更改为 upsert 以防止流星尝试插入具有相同 _id
  2. 的新文档
  3. 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
    }
  });
});