Reputation: 815
Why does the template get rendered the number of times that correlates with the Each in my template.
<template name="carousel">
<div class="pikachoose">
<ul class="carousel" >
{{#each article}}
<li><a href="#"><img src="{{image}}" width="500" height="250" alt="picture"/></a><span>{{caption}}</span></li>
{{/each}}
</ul>
</div>
</template>
Template.carousel.article = function () {
return News.find({},{limit: 3});
}
Template.carousel.rendered = function() {
//$(".pika-stage").remove();
alert($(".carousel").html());
//$(".carousel").PikaChoose({animationFinished: updateNewsPreview});
}
In this case it would alert 3 times.
Upvotes: 0
Views: 119
Reputation: 19544
That's the way Meteor handles data updates. Your article
data function returns a cursor that is to be used in the template. Initially, the cursor is empty, and data is pulled from the server, one article at a time. Each time an article is fetched, the contents of cursor are changed (it now has one more article), and therefore the reactive article
method causes template to rerender.
If you need to be sure that your code runs only once, there are several possibilities depending on what you need.
The easiest one is just to use created
instead of rendered
.
If you modify DOM elements, you can also mark elements you modify so that you won't process them twice:
Template.carousel.rendered = function() {
_.each(this.findAll('.class'), function(element){
if($(element).data('modified')) return;
$(element).data('modified', true);
...
});
};
You can disable reactivity for the cursor, though it's a sad solution:
Articles.find(..., {reactive: false});
The most invasive, but also the most versatile is to observe when the data is fully loaded:
Deps.autorun(function() {
Meteor.subscribe('articles', {
ready: function() {
...
},
});
});
Upvotes: 1
Reputation: 382
The issue may have to do with the use of the .rendered
callback. Each time the loop runs the DOM is updated so the callback will run again.
When I had this problem in the past, I found it helpful to use Meteor event handlers whenever possible, to eliminate load order issues like this one. In this case, maybe you could try a timeout, so that that the .remove()
and .PikaChoose()
calls only run after the DOM has been quiet for a certain interval. Hope that works for you.
Upvotes: 0