2

简而言之,我想做:

Meteor.publish('items', function(){ 
  return Item.find({categoryId: Categories.find({active: true} });
});

作为“类别”一部分的“活动”标志会定期更改。

我还尝试通过利用 Categories 集合上的反应性来取消/重新订阅 Items 集合,它可以工作,不幸的是它会重新触发对 Categories 集合的任何修改,无论它是否影响“活动”标志。

我有哪些选择?

4

4 回答 4

1

当类别在服务器上被标记为非活动时,没有解决项目在本地未被“删除”的问题。解决方案(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);
});

我意识到这并不完美(仍然使用客户端代码),但它可以工作并且它是我能想到的最干净的。我希望它可以帮助某人!

于 2013-07-29T13:53:37.740 回答
0

一种可能的解决方案是创建一个依赖对象,观察所有类别的变化,并在活动标志被切换时触发 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} });
});
于 2013-07-27T22:18:44.110 回答
0
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再次运行。

于 2013-07-27T23:53:26.240 回答
0

我使用以下发布来解决类似的问题。我认为只有一行嵌套的查询会限制反应性。在发布函数中打破一个查询似乎可以避免这个问题。

//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上推出了一个工作版本。如果您只需要发布功能,则如上所述。

于 2013-07-28T02:06:38.417 回答