Reputation: 117
I'm quite new to Meteor and I'm having trouble trying to understand the "rendered" event on templates.
Assuming I have this two templates:
<template name="parent">
<div id="list">
{{#each childs}}
{{> child}}
{{/each}}
</div>
</template>
<template name="child">
<div class="item">
<!-- content -->
</div>
</template>
and these two events:
Template.parent.rendered = function () {
console.log('parent');
};
Template.child.rendered = function () {
console.log('child');
};
I always get this from console:
> parent > child > child > child
So basically the parent template triggers "rendered" before the inner templates have finished rendering. Because of that I'm unable to do execute any post operations to the DOM like jquery plugins. e.g:
Template.parent.rendered = function () {
$('#list').myplugin();
};
Since this gets executed before inner templates are rendered it breaks the plugin.
Is there a workaround or a meteor event that I can use to safely now when a template is fully rendered, including it's inner templates?
Upvotes: 4
Views: 447
Reputation: 64312
My general advice for problems like this is you should look for a way to activate your plugin after rendering each child, rather than after rendering the parent - even if it means making extra calls to the plugin. If you can do that then it also solves the related problem of what happens when more children are added sometime later (of course this may not apply in your case).
It's hard to give a precise answer without knowing more details about what your plugin does but I can give an example from one of my applications:
I had to make sure all of the children were the same height as the tallest child. My initial reaction was that I had to somehow wait for all of the children to finish rendering and then adjust their heights once. The easier solution was just to resize all of them every time any of them were rendered. Sure it's O(N^2) comparisons, but it's still fast for a small list and works even when new children are added.
Note that if you absolutely had to call the plugin once and no new children could be added later, you could try an ugly hack to initialize the plugin only after all of them were rendered. For example:
Template.child.rendered = function () {
if ($('.child').length === Children.find().count()) {
$('#list').myplugin();
}
};
Upvotes: 1