简而言之,我想做:
Meteor.publish('items', function(){
return Item.find({categoryId: Categories.find({active: true} });
});
作为“类别”一部分的“活动”标志会定期更改。
我还尝试通过利用 Categories 集合上的反应性来取消/重新订阅 Items 集合,它可以工作,不幸的是它会重新触发对 Categories 集合的任何修改,无论它是否影响“活动”标志。
我有哪些选择?
简而言之,我想做:
Meteor.publish('items', function(){
return Item.find({categoryId: Categories.find({active: true} });
});
作为“类别”一部分的“活动”标志会定期更改。
我还尝试通过利用 Categories 集合上的反应性来取消/重新订阅 Items 集合,它可以工作,不幸的是它会重新触发对 Categories 集合的任何修改,无论它是否影响“活动”标志。
我有哪些选择?
当类别在服务器上被标记为非活动时,没有解决项目在本地未被“删除”的问题。解决方案(ish)是:
客户:
Categories.find({active: true}).observeChanges({
added: function(){
itemsHandle && itemsHandle.stop();
itemsHandle = Meteor.subscribe("items");
}
});
服务器:
Meteor.publish('items', function(){
var category = Categories.findOne({active: true});
return category && Items.find({categoryId: Categories.findOne({active: true}._id);
});
我意识到这并不完美(仍然使用客户端代码),但它可以工作并且它是我能想到的最干净的。我希望它可以帮助某人!
一种可能的解决方案是创建一个依赖对象,观察所有类别的变化,并在活动标志被切换时触发 dep 变化。这些方面的东西:
var activeCount = Categories.find({active: true}).count();
var activeDep = new Deps.Dependency();
Deps.autorun(function() {
var activeCountNow = Categories.find({active: true}).count();
if(activeCountNow !== activeCount) {
activeCount = activeCountNow;
activeDep.changed();
}
});
Meteor.publish('items', function(){
activeDep.depend();
return Item.find({categoryId: Categories.find({active: true} });
});
注意:我只是在验证活动类别的数量是否发生变化,这样我就不必将活动列表保留在内存中。根据您的应用程序的工作方式,这可能合适也可能不合适。
编辑:评论中提到的双面风味:
客户:
var activeCount = Categories.find({active: true}).count();
var activeDep = new Deps.Dependency();
Deps.autorun(function() {
var activeCountNow = Categories.find({active: true}).count();
if(activeCountNow !== activeCount) {
activeCount = activeCountNow;
activeDep.changed();
}
});
Deps.autorun(function(){
activeDep.depend();
Meteor.subscribe('items', new Date().getTime());
});
服务器:
Meteor.publish('items', function(timestamp) {
var t = timestamp;
return Item.find({categoryId: Categories.find({active: true} });
});
Meteor.startup(function() {
Categories.find().observe({
addedAt: function(doc) {
trigger();
},
changedAt: function(doc, oldDoc) {
if(doc.active != oldDoc.active) {
trigger();
}
},
removedAt: function(oldDoc) {
trigger();
}
});
});
现在,该trigger函数应该导致发布重新运行。这次在客户端上很容易(更改订阅参数)。我不确定如何在服务器上执行此操作 - 可能会publish再次运行。
我使用以下发布来解决类似的问题。我认为只有一行嵌套的查询会限制反应性。在发布函数中打破一个查询似乎可以避免这个问题。
//on server
Meteor.publish( "articles", function(){
var self= this;
var subscriptions = [];
var observer = Feeds.find({ subscribers: self.userId }, {_id: 1}).observeChanges({
added: function (id){
subscriptions.push(id);
},
removed: function (id){
subscriptions.splice( subscriptions.indexOf(id)) , 1);
}
});
self.onStop( function() {
observer.stop();
});
var visibleFields = {_id: 1, title: 1, source: 1, date: 1, summary: 1, link: 1};
return Articles.find({ feed_id: {$in: subscriptions} }, { sort: {date: -1}, limit: articlePubLimit, fields: visibleFields } );
});
//on client anywhere
Meteor.subscribe( "articles" );
这是另一个SO 示例,如果您认为可以接受,它会通过 subscribe 从客户端获取搜索条件。
更新:由于 OP 努力实现这一目标,我做了一个要点并在meteor.com上推出了一个工作版本。如果您只需要发布功能,则如上所述。