Meteor Iron-Router:等待订阅顺序

时间:2016-09-12 08:37:22

标签: meteor iron-router subscription

我的铁路由器中定义了以下路由:

    this.route("/example/:id", {
    name: "example",
    template: "example",
    action: function () {
        this.wait(Meteor.subscribe('sub1', this.params.id));
        this.wait(Meteor.subscribe('sub2', <<data of sub1 needed here>>));

        if (this.ready()) {
            this.render();
        } else {
            this.render('Loading');
        }
    }
});

我想在渲染我的实际模板之前等待sub1和sub2。问题是我需要一个数据,它是sub2订阅的sub1结果的一部分。

我如何等待订阅顺序?这样我就可以分两步分开等待并等待我的第一个订阅完成。然后启动第二个订阅,然后设置this.ready()来呈现模板?

我想到的解决方法是使用Reactive-Vars进行订阅,并且不要使用由iron-router提供的.wait和.ready。但我想使用铁路由器或Meteor本身提供的更方便的解决方案。你知道更好的解决方案吗?

感谢您的回答!

2 个答案:

答案 0 :(得分:1)

发布复合包:

如果第二个订阅反应依赖于第一个数据集中的某些字段 - 并且是否会有多对多的&#34;加入&#34;关联,可能值得研究reywood:publish-composite包:

它提供了一种简洁易用的方法来管理具有层次关系的集合的关联订阅。

<强> 公开:

Meteor.publishComposite('compositeSub', function(id) {
    return {
        find: function() {
            // return all documents from FirstCollection filtered by 'this.params.id' passed to subscription
            return FirstCollection.find({ _id: id });
        },
        children: [
            find: function(item) {
                // return data from second collection filtered by using reference of each item's _id from results of first subscription
                // you can also use any other field from 'item' as reference here, as per your database relations
                return SecondCollection.find({ itemId: item._id });
            }
        ]
    }
});

<强> 订阅:

然后您可以使用以下命令在路由器中订阅:

Meteor.subscribe('compositeSub', this.params.id);

路由器挂钩:

作为一个建议,铁路由器中的挂钩非常有用,因为它们可以为您处理很多事情。那么为什么不使用管理this.waitloading状态的waitOn挂钩呢?

this.route('/example/:id', {
  name: "example",
  template: "example",
  // this template will be rendered until the subscriptions are ready
  loadingTemplate: 'loading',

  waitOn: function () {
    // return one handle, a function, or an array
    return Meteor.subscribe('compositeSub', this.params.id);  
    // FYI, this can also return an array of subscriptions
  },

  action: function () {
    this.render();
  }
});

您可以使用configure选项添加加载事件的模板:

Router.configure({
    layoutTemplate: 'layout',
    loadingTemplate: 'loading'
});

关于相关评论的注释:

如果两个订阅仅依赖于传递给它的相同id参数,则可以使用以下注释中的 @ abj27 中提到的内容 - 但是,这不是似乎就是这样,按照你的例子:

<强> 公开:

Meteor.publish("subOneAndTwo", function (exampleId) {
  check(exampleId, String);
  return [
    FirstCollection.find({ _id: exampleId });
    SecondCollection.find({ firstId: exampleId })
  ];
});

<强> 订阅:

Meteor.subscribe('subOneAndTwo', this.params.id);

因此,只需检查您需要的内容并相应地使用解决方案。

答案 1 :(得分:0)

https://github.com/kadirahq/subs-manager

使用此软件包,您可以为变量分配订阅。然后,您可以检查该变量的就绪状态。经过多年的努力,我才开始工作。

这是我的代码段,但是奇怪的是我不得不将其包装在1毫秒的超时时间内才能工作...

``` Router.route('/ activity /:activityId',function(params){

var params = this.params;

setTimeout(function(){

    var thePage = window.location.href.split("/");; 
    window.thePage = thePage[4];

    dbSubscriptionActivites.clear();
    window.thisDbSubscriptionActivites = "";
    window.thisDbSubscriptionActivites = dbSubscriptionActivites.subscribe("activityByPage", window.thePage);


    Tracker.autorun(function() {
        if(window.thisDbSubscriptionActivites.ready()) {

            dbSubscriptionComments.clear();
            window.thisDbSubscriptionComments = "";
            window.thisDbSubscriptionComments = dbSubscriptionComments.subscribe('fetchComments', "activity", Activities.findOne({})._id);

            BlazeLayout.render("activity"); 
            $('body').removeClass("shards-app-promo-page--1");

        }
    });

},1); // Must wait for DOM? 

}); ```

检查:window.thisDbSubscriptionActivites = dbSubscriptionActivites.subscribe(“ activityByPage”,window.thePage);

我正在设置为窗口变量,但是您可以执行const mySub = ...

然后,您稍后再检查自动运行功能。

您可以看到我正在订阅。

我想我真的应该将BlazeLayout渲染移到另一个.ready()检查注释。