【问题标题】:Meteor reactive filtering of published collection已发布集合的流星反应过滤
【发布时间】:2015-10-03 18:27:54
【问题描述】:

我有两个收藏问题和模拟:

// Issues
{
  issueId: 1000, 
  appears: '2014-01-01',
  ...
}
// Simulations
{
  history: [50,200,30], 
  date: '2014-01-01',
  ..
}

如何重新发布不在单个模拟中的问题。

Meteor.publish('issues', function () {
    var simulation = Simulations.findOne({}),
        history = lodash.pluck(simulation.history, 'issueId');
    return Issues.find({
        issueId: {$nin: history},
        appears: {$lte: simulation.date}
    }, {limit: 12});
});

当我更改模拟日期或将 issueIds 推送到模拟历史记录时,我希望更改发布的数据。 我发现了一些带有关系的包发布,但我无法理解如何使用它,这是我真正需要的。 https://atmospherejs.com/cottz/publish-with-relations

【问题讨论】:

    标签: javascript mongodb meteor


    【解决方案1】:

    您的发布函数不会根据参数响应式运行。我的意思是一旦发布函数返回了游标,那个查询返回的记录集的更改将与客户端同步,但是查询的更改 不会有任何影响。因此,如果您要将另一个文档添加到与 original 查询 {issueId: {$nin: originalHistory}, appears: {$lte: originalSimulation.date}} 匹配的 Issues 集合中,它将被发送到客户端,但如果您对 Simulations 集合进行更改将不起作用,因为发布函数已经返回了光标。

    实现您的目标的一种方法是订阅自动运行块中的发布,并传递您可以根据需要更新的反应参数。将订阅保持在自动运行块内不仅会使其反应性地重新运行,而且会自动取消旧订阅,这样您就不会不断增加服务器负载。像这样的:

    服务器:

    Meteor.publish('issues', function (simulation, history) {
        return Issues.find({
            issueId: {$nin: history},
            appears: {$lte: simulation.date}
        }, {limit: 12});
    });
    

    客户:

    Tracker.autorun(function() {
        var simulation = Simulations.findOne({}),
            history = lodash.pluck(simulation.history, 'issueId');
        Meteor.subscribe('issues', simulation, history);
    });
    

    请注意,通过观察更改并利用低级发布 API,您可以通过多种方式仅在服务器上实现此目的。更多关于如何做到这一点here。这样做几乎肯定会更复杂,但可能会带来性能优势,具体取决于您在客户端和服务器上有多少可用计算能力,

    【讨论】:

      【解决方案2】:

      我尝试过@richsilv 方法,但最后我还是使用了https://atmospherejs.com/mrt/reactive-publish 我不知道这是不是正确的方法,但由于它自动工作,所以现在就可以了。

      Meteor.reactivePublish('issues', function () {
          var simulation = Simulations.findOne({}, {reactive: true}),
              history = lodash.pluck(simulation.history, 'issueId');
          return Issues.find({
              issueId: {$nin: history},
              appears: {$lte: simulation.date}
          }, {limit: 12});
      });
      

      【讨论】:

        【解决方案3】:

        您可以使用reactive-publish 包(我是作者之一)。这是对@slobodan.blazeski 提到的包的重写:

        Meteor.publish('issues', function () {
            this.autorun(function (computation) {
                var simulation = Simulations.findOne({}, {fields: {history: 1, date: 1}}),
                    history = lodash.pluck(simulation.history, 'issueId');
                return Issues.find({
                    issueId: {$nin: history},
                    appears: {$lte: simulation.date}
                }, {limit: 12});
            });
        });
        

        重要的是限制模拟文档中您感兴趣的字段,以便autorun 在其他一些字段更改时不会不必要地重新运行。

        【讨论】:

        • 请避免在多个答案上复制/粘贴此样板文件。虽然您已针对每个问题调整了您的帖子,但这可能会被视为可疑/垃圾邮件。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        • 1970-01-01
        • 2015-02-23
        • 2015-01-24
        • 2015-07-22
        相关资源
        最近更新 更多