在我目前正在研究的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;
答案 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'
的任何其他数据分开。