How do I use meteor subscriptionsReady() to ensure data is ready before rendering template?

雨燕双飞 提交于 2019-12-08 06:01:22

问题


One of the challenges of using a framework that is newish and under development is that the advice you find on the web is often outdated. This applies doubly to Meteor where the SO answers and web articles are often for a pre 1.0.x or an early 1.0.x version, or for the previous version of iron-router, or before they introduced a feature last week, and so on.

Still puzzling over how to use the subscriptionsReady() function in the context of having a template wait until subscriptions are ready for it. I certainly need it since my template tries to render without its data about 3/4 of the time.

How do I use subscriptionsReady()? I've seen examples which use it in the html which I think is kind of dumb (fuzzing presentation and function). How do I use it in the code portion of a template?

Is it used in iron-router with some kind of waitOn? Do I wrap it with a while loop in my template renderer? Can you give a simplified example?

Obligatory code stuff... My route for my template:

Router.route('/', {
  path: '/',
  template: 'navmenu',
  onBeforeAction: function() {
    this.next();
  }
});

My subscriptions:

// Chapters
ChapterCollection = new Mongo.Collection("ChapterCollection");

if(Meteor.isClient){

    Meteor.subscribe('users');
    Meteor.subscribe('roles');
    Meteor.subscribe('ChapterCollection');
}

The html portion is pretty plain, some HTML wrapped in a template tag.

My template code:

Template.navmenu.rendered = function() {

    // Load all chapters from collections
    // Unless it decides to delay and then we are *%&@ed
    chapterArray = ChapterCollection.find().fetch();

    ... other stuff ...
}

Thanks for the help.


回答1:


The Iron router way:

Router.route('/', {
  name: 'nameOfRoute',

  waitOn: function () {
   // we will wait for these subsciptions
    return [Meteor.subscribe('users'), Meteor.subscribe('roles'), Meteor.subscribe('ChapterCollection')]
  },

  action: function () {
  // this.ready() is true if all items in the wait list are ready
    if (this.ready()) {
        this.render('yourTemplate');
    }
    else {
        // if not ready, you can render another template in the meantime.
        this.render('Loading');
        }
    }
});

Within the action function, you may also create template helpers. For example, if one of the subscriptions in the waitOn function returns documents from a collection called ChapterCollection, the helper called helperA will pass this data to the template:

if (this.ready()) {
    this.render('yourTemplate', { data: {helperA: ChapterCollection.find()} });
}

html:

<template name="yourTemplate">
 //use the #each or #with block with respect to the data being returned. E.g
  {{#each helperA}}
    {{fieldName}}
  {{/each}}
</template>

The Meteor way:

You can use this.subscribe from an onCreated callback to specify which data publications this template depends on

step 1:

So a simple step by step explanation: Once the template has been created, these subscriptions are called. Note here, it's what we do in the template in the step 2. prevents the 'contents' from rendering until the subscriptions are ready

Template.yourtemplate.onCreated(function () {
  this.subscribe("users");
  this.subscribe("roles");
  this.subscribe("ChapterCollection");
});

Step 2:

<template name="yourTemplate">

    {{#if Template.subscriptionsReady}}

    // all of the template contents here will be rendered ONLY when the subscriptions within the onCreated callbacks are ready.

    {{else}}

    // if subsciption is not ready, you may show something else here. E.g. "Loading...."

    {{/if}}

</template>



回答2:


There is waitOn method for waiting for subscriptions in Iron Router:

Router.route('/', {
  name: 'navmenu',
  waitOn: function() {
    return [
      Meteor.subscribe('users');
      Meteor.subscribe('roles');
      Meteor.subscribe('ChapterCollection');
    ];
  },
  onBeforeAction: function() {
    this.next();
  }
});

So you can remove your subscriptions in your client-side code.

And your "template" option should be "name". Read Iron Router docs.



来源:https://stackoverflow.com/questions/29788763/how-do-i-use-meteor-subscriptionsready-to-ensure-data-is-ready-before-renderin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!