关联Meteor集合订阅返回的每个模型

时间:2016-12-16 15:45:12

标签: mongodb meteor subscription

在我目前正在研究的Meteor应用程序中,一些集合可能有多个同时订阅(即一个用于初始获取,另一个用于搜索更多数据等)。当然,我不希望将整个集合下载到客户,所以我依靠subscriptions manager和需要的方法。

问题在于,一旦获取了数据,客户端上的集合就包含了所有订阅的全部内容,我不知道如何辨别从哪个订阅中获取哪些数据(即最初获取哪些数据) ,搜索等等。)

我曾想过为每个获取的数据添加一个订阅UID(一个数组,因为一些数据可以从多个订阅中获取),但这看起来很容易,并且很容易被清理干净。

是否存在关联和识别哪个订阅获取哪些数据的解决方案?

更新

所以票价,this answer似乎解决了部分问题,但这并不是我认为“干净”的解决方案。

// ctx being the Metheor.subscribe context (i.e. const ctx = this;)

function transform(doc) {
  if (searchKey) {
    doc._searchKey = searchKey;
  }
  return doc;
}

const cursor = InventoryItems.find(filter, options);
const observer = cursor.observe({
  added(doc) {
    ctx.added(InventoryItems._name, doc._id, transform(doc));
  },
  changed(newDoc, oldDoc) {
    ctx.changed(InventoryItems._name, newDoc._id, transform(newDoc));
  },
  removed(oldDoc) {
    ctx.removed(InventoryItems._name, oldDoc._id);
  }
});

ctx.onStop(() => {
  observer.stop();
});

return cursor;

1 个答案:

答案 0 :(得分:2)

此答案描述了将数据发布到仅客户端集合的方法。

如果要分离某些数据,可以将其发布到其他集合:

//client

const TempCollection = new Meteor.Collection('temp', {defineMutationMethods: false});

Meteor.subscribe('temp.query', 'queryParams');

这定义了一个没有设置变异方法的集合,因此在客户端上对它进行的任何更改都不会发送到服务器(因为它没有意义)。请注意,应在服务器发布中使用集合名称(在本例中为temp

// server
const ActualCollection = new Mongo.Collection('real_collection_name');

function publishForTarget(sub, cursor, targetName) {
    return Mongo.Collection._publishCursor(cursor, sub, targetName);
}

Meteor.publish('temp.query', function(/*params*/) {
    let query = {/*...*/};
    let targetName = 'temp'; // or get it from the client for dynamically-named client-side collections. 
    let cursor = ActualCollection.find(query);    
    publishForTarget(this, cursor, targetName);

    return this.ready();
});

这使用了未记录的Mongo.Collection._publishCursor方法,当返回游标时,标准发布也使用该方法。

其实施:

Mongo.Collection._publishCursor = function (cursor, sub, collection) {
  var observeHandle = cursor.observeChanges({
    added: function (id, fields) {
      sub.added(collection, id, fields);
    },
    changed: function (id, fields) {
      sub.changed(collection, id, fields);
    },
    removed: function (id) {
      sub.removed(collection, id);
    }
  });

  // We don't call sub.ready() here: it gets called in livedata_server, after
  // possibly calling _publishCursor on multiple returned cursors.

  // register stop callback (expects lambda w/ no args).
  sub.onStop(function () {observeHandle.stop();});

  // return the observeHandle in case it needs to be stopped early
  return observeHandle;
};

它会观察游标的变化,并在事情发生变化时调用订阅生命周期方法(转换为DDP突变消息)。我们正在使用targetName替换真实的集合名称。

这意味着所有结果都将发布到客户端上的'temp'集合中,并且会与正常查询并发布到'real_collection_name'的任何其他数据分开。