Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
270 views
in Technique[技术] by (71.8m points)

publish subscribe - Callback when all Template items finished rendering in Meteor?

I'm getting a collection of records and placing them in a Template, having them rendered {{#each}} and I want to display a loading icon until the last DOM node is rendered.

My problem is that I have not found a way to query a state/fire a callback on the last item rendered aka the last DOM node to be updated/re-drawn.

It looks a bit like this in my HTML file:

<template name="stuff">
    {{#each items}}
        <div class="coolView">{{cool_stuff}}</div>
    {{/each}}
</template>

And in the client-side JS file:

// returns all records of Stuff belonging to the currently logged-in user
Template.stuff.items = function () {
    Session.set('loading_stuff', true);
    return Items.find({owner: Meteor.userId()}, {sort: {created_time: -1}});
};

Template.stuff.rendered = function() {
    // every time something new is rendered, there will have been loading of the DOM. 
    // wait a short while after the last render to clear any loading indication.
    Session.set('loading_stuff', true);
    Meteor.setTimeout(function() {Session.set('loading_stuff', false);}, 300);
};

The Session variable loading_stuff is queried in a Handlebars helper, returning the name of the loading class (with a loader icon GIF) if it's true.

The reason I do the awkward Meteor.setTimeout is because Template.rendered is called after every single item that was rendered into the Template. So I need to re-confirm that it is still loading, but give it some time to either load the next one or to finish rendering them all, with a little pause until it sets loading_stuff to false.

How do I reliably query/callback at the end of all DOM updates (for a particular Template or for the whole page) the proper Meteor way?

Many thanks.

EDIT

The solution with using the subscribe() onReady() callback only partially works:

Templates are seemingly called multiple (2-3) times before the rendering even starts, but after the data has returned from the server that the Template relies on to render. This means that that it's 'finished' loading data, but the DOM is still being rendered. I will play around with Meteor.autorun() and see if I can find a reliable hook somewhere to do this properly. In the meantime, I guess my original question still remains:

How do I know when the entire Template/page has finished rendering?

FINAL EDIT:

At the end of the day, based on how the DOM is structured, it's up to the developer have a rock-solid DOM and attach the appropriate callbacks as best as possible to the elements he/she wants to check the state of. It may seem like an anti-climatic no-brainer, but for me the only way to know the final element of a Template is rendered is to have an element with a special id rendered at the very end of a Template that signals the end of the render and attach a .livequery callback to it. I hope that Meteor will incorporate a more unified and global support for checking this state in the future.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Nesting an item template inside the current one might actually help?

<template name="stuff">
   {{#each items}}
     {{> itemTemplate}}
   {{/each}}
</template>

<template name="itemTemplate">
   <div class="coolView">{{cool_stuff}}</div>
</template>

Now the callback on Template.itemTemplate.rendered may run every time new item is updated into the DOM.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...