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

时间:2015-04-05 23:16:54

标签: mongodb meteor cursor

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

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

2 个答案:

答案 0 :(得分:1)

  

meteor尝试将更改后的文档重新插入本地   集合

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

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

详细了解更新操作符here

答案 1 :(得分:1)

解决方案:

  1. 我将insert更改为upsert,以防止流星尝试使用相同的_id
  2. 插入新文档
  3. Meteor不允许在客户端上替换整个文档,因此我指定了要更新的字段:
  4. 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
        }
      });
    });