流星集合不更新客户端上的订阅

Posted

技术标签:

【中文标题】流星集合不更新客户端上的订阅【英文标题】:Meteor collection not updating subscription on client 【发布时间】:2013-03-18 19:25:59 【问题描述】:

我是 Meteor 和 Mongo 的新手,即使我不想要它,我也需要一些关系。

我有一个名为 Feeds 的集合和另一个名为 UserFeeds 的集合,其中我有一个 feedid 和一个用户 ID,我在服务器上发布用户提要,如下所示:

Meteor.publish('feeds', function()
    return Feeds.find(_id:$in:_.pluck(UserFeeds.find(user:this.userId).fetch(),'feedid'));
);

我在 UserFeeds 上找到用户,获取它(返回一个数组)并将其提取为只有 feedid 字段,然后在 Feeds 集合中找到这些提要。

并像这样在客户端上订阅:

Deps.autorun(function()
   Meteor.subscribe("feeds");
);

问题是当我添加一个新的提要和一个新的用户提要时,客户端没有收到更改,但是当我刷新页面时,新的提要确实出现了。

知道我在这里缺少什么吗?

谢谢。

【问题讨论】:

面对这种情况的解决方案是什么----***.com/questions/42652958/… 【参考方案1】:

我也遇到过。事实证明,服务器上的发布函数不会响应式地重新运行:如果它们返回一个 Collection 游标,就像你正在做的那样(和大多数发布函数一样),那么发布函数将运行一次,Meteor 将存储游标并且仅在光标的内容更改时才发送更新。这里重要的是,当query 更改时,Meteor不会重新运行发布功能,因此,Collection.find(query) 也不会。如果您希望发布函数重新运行,那么到目前为止我所做的方法是设置发布函数以接收参数。这样,其集合响应式更新的客户端可以响应式地重新订阅。代码看起来像:

// client
Meteor.subscribe('user_feeds');

Deps.autorun(function() 
  var allFeeds = UserFeeds.find(user: Meteor.userId()).fetch();
  var feedIds = _.pluck(allFeeds,'feedid');
  Meteor.subscribe('feeds',feedids);
);

// server
Meteor.publish('feeds',function(feedids) 
  return Feeds.find(_id: $in: feedids);
);

我相信 Meteorite 包publish-with-relations 就是为了解决这个问题,虽然我没用过。

编辑:我相信发布功能会在 userId 更改时重新运行,这意味着您可以在发布敏感数据之前进行服务器端检查以确保用户已登录。

【讨论】:

我在为组/角色使用 Alanning Roles 包并尝试根据用户角色(更改)过滤发布时遇到同样的问题。我正在订阅 Iron Router waitOn,所以我想我需要把它移到某个地方。您是否建议将订阅移至createrendered 如果有三个集合怎么办:用户、项目和权限。项目根据权限发布给用户。权限可以更改,我们希望立即反映该更改。出于安全原因,我们不能仅仅通过“Meteor.publish”函数接受来自客户端的用户 ID 或权限 ID 或有效权限,对吧?【参考方案2】:

我认为你的问题是你在这里使用的 .fetch() ......

UserFeeds.find(user:this.userId).fetch()

…消除反应。

.fetch() 返回一个数组而不是游标,并且该数组不会是响应式的。

http://docs.meteor.com/#fetch

【讨论】:

【参考方案3】:

试试这个...

Meteor.autosubscribe(function()
    Meteor.subscribe("feeds");
);

在模板 JS 中 ...

Template.templateName.feeds = function() 
  return Feeds.find() # or any specific call
;

html ...

#each feeds
   do some stuff
else
   no feed
/each

【讨论】:

嗨,问题不在客户端,而是在服务器端,客户端渲染提要很好,问题是当创建新提要并与用户相关时它不会推送对客户的改变。【参考方案4】:

您可以使用reactive-publish 包(我是作者之一)。它允许您创建依赖于另一个查询结果的发布端点。在您的情况下,请查询UserFeeds

Meteor.publish('feeds', function () 
    this.autorun(function (computation) 
        var feeds = _.pluck(UserFeeds.find(user: this.userId, fields: feedid: 1).fetch(), 'feedid');
        return Feeds.find(_id: $in: feeds);
    );
);

重要的部分是您将UserFeeds 字段仅限于feedid,以确保autorun 在您不关心的UserFeeds 中的其他字段更改时不会重新运行。

【讨论】:

以上是关于流星集合不更新客户端上的订阅的主要内容,如果未能解决你的问题,请参考以下文章

流星订阅不更新集合的排序顺序

有没有办法告诉流星集合是静态的(永远不会改变)?

Meteor 集合获取返回空数组但已订阅

流星一次或“静态”发布,无需收集跟踪

流星中minimongo的原因是啥

在新数据到达 Meteor 时对其进行动画处理