当收集子字段在发布中更改时,订阅不会更新(使用$ slice)

时间:2017-04-05 21:27:29

标签: mongodb meteor

我有一个发布,它接收订阅中的参数,以确定从集合中的数组返回的记录数(使用$ slice)。我遇到的问题是,当通过订阅发送新参数时,我的模板上的数据不会刷新。这是我的代码:

公开:

Meteor.publish('Conversations', function (record_limit) {
  var bunchsize = 50;
  var multiplier = 1;
  if (record_limit) {
    multiplier = record_limit;
  } 
  var publimit = bunchsize * multiplier;
  return Conversations.find({users:{$in:[this.userId]}},{fields:{"lstmsg":1,  "msg":{"$slice":-publimit}}});        
});

触发加载更多数组对象:

var convCounter = 1;
Template.conversation.events({
  'click .js-loadmore': function() {
    convCounter = convCounter + 1;
    Deps.autorun(function() { Meteor.subscribe("Conversations",convCounter); });
  }
});

为什么我的模板上没有刷新订阅的任何建议?它总是只显示“msg”字段的50个项目,而它上面有200多个项目。提前谢谢。

2 个答案:

答案 0 :(得分:0)

尝试使用autorun代替您将订阅包装在模板onCreated回调中的Template.conversation.onCreated(function() { this.convCounter = new ReactiveVar(1); this.autorun(() => { this.subscribe('Conversations', this.convCounter.get()); }); }); Template.conversation.events({ 'click .js-loadmore': function(event, instance) { instance.convCounter.set(instance.convCounter.get() + 1); } }); 内。

ReactiveVar

当您处理点击事件时,它会更新$slice,然后会导致之前的出版物停止并开始新的出版物(使用新的record_limit值)。

您还必须修改您的发布并使用较低级别的api,以欺骗合并框向客户端发送子字段更改(否则,如果您重新订阅新的msg值,客户端记录不会使用_id子字段值进行更新。注意,这种方法只有在订阅客户端使用"只读"时尚,因为我们修改了发送的Meteor.publish('Conversations', function (record_limit) { var bunchsize = 50; var multiplier = 1; if (record_limit) { multiplier = record_limit; } var publimit = bunchsize * multiplier; const handle = Conversations.find({ users: { $in: [this.userId] } }, { fields: { "lstmsg": 1, "msg": { "$slice": -publimit } } }).observe({ added: (doc) => { this.added("Conversations", doc._id + publimit, doc); }, changed: (newDoc, oldDoc) => { this.changed("Conversations", newDoc._id + publimit, newDoc); }, removed: (oldDoc) => { this.removed("Conversations", oldDoc._id + publimit); }, }); this.ready(); this.onStop(() => { handle.stop(); }); }); 字段以欺骗合并框。

record_limit

理论上,在使用新的_id参数重新订阅时,先前在客户端上加载的任何数据(来自先前的订阅)将被丢弃并替换为新数据,因为文档{{1 } field是不同的(因为我们使用record_limit作为id的一部分。)

答案 1 :(得分:0)

如文档中所述,似乎Meteor不会在子字段级别(例如在我的情况下,在msg内部)发生更改时刷新订阅:

  

目前,多个订阅仅发布同一文档   在合并期间比较顶级字段。这意味着如果   文档包括相同顶级的不同子字段   字段,并非所有这些都将在客户端上提供。我们希望   在将来的版本中解除此限制。

检查问题主题: https://github.com/meteor/meteor/issues/3764#issuecomment-75853901

问题依旧开放......大转弯。

替代方法:我发现使其工作的方法是每次我需要通过$ slice参数从数组中检索更多字段时停止先前的订阅,如下所示:

lastSub = "";
convCounter = 1;
Template.conversation.onCreated(function() {
   lastSub = Meteor.subscribe("Conversation", convCounter);
});

Template.conversation.events({
  'click .js-loadmore': function() {
     convCounter = convCounter + 1; 
     if (lastSub) {lastSub.stop();}
        lastSub = Meteor.subscribe("Conversation", convCounter);
  }   
});

对于数据访问而言,解决方法可能效率低下,但我希望我的用户不会经常浏览旧对话。