javascript - Why is Template.mytemplate.rendered getting triggered twice when trying to animate live changes in Meteor.js? -
i have issues figuring out how meteor.rendered
works exactly. i'm trying animate live change in meteor, this question does. whenever click on element, want blink.
however, template gets rendered twice every time element clicked, in turn triggers animation 2 times. here code:
template
<body> {{> myitemlist}} </body> <template name="myitem"> <div class="item {{selected}}"> <h4>{{name}}</h4> <p>{{description}}</p> </div> </template> <template name="myitemlist"> {{#each items}} {{> myitem}} {{/each}} </template>
javascript
template.myitemlist.helpers({ items: function () { return items.find(); } }); template.myitem.helpers({ selected: function () { return session.equals('selected', this._id) ? "selected" : ""; } }); template.myitem.events({ 'click .item' : function () { session.set('selected', this._id); } }); template.myitem.rendered = function () { $(".item.selected").fadeout().fadein(); };
my understanding every time session.set
called, every template uses session.get
same key re-runed, explained in documentation. guess somehow, session.equals
causes 2 reruns of template, maybe? if change selected
helper code:
template.myitem.helpers({ selected: function () { if (session.get("selected")) === this._id) return "selected"; else return ""; } });
then animation gets triggered 3 times instead of 2.
with in mind, questions are:
- why
template.myitem.rendered
getting triggered twice? goes on behind scenes? - how can fix have animation triggered once?
answer details
so comment on @xyand solutions:
- moving animations
click
eventmeteor.settimeout()
works, felt bit hacky me. the solution quite simple, , given in this question. code looks this:
template.myitem.rendered = function () { if (session.equals('selected', this.data._id)) $(this.firstnode).fadeout().fadein(); };
i first tried on different project had different template markup , didn't work, why created minimal project see things went wrong. turns out work, absolutely need have sub-template myitem
called inside myitemlist
template. if template looks this,
<template name="myitemlist"> {{#each items}} <div class="item {{selected}}"> <h4>{{name}}</h4> <p>{{description}}</p> </div> {{/each}} </template>
and every helper function , rendered
function called myitemlist
template, code won't work because inside rendered
function, template instance have .data
attribute undefined.
the template gets rendered twice because 2 different instances of same template rendered. 1 changes selected
"selected"
, changes ""
. explains why have 3 renders when switch equals
get
.
mixing imperative javascript declarative mess. here 2 suggestions:
add
if
insiderendered
function make sure call transition in selected item template instance.move transition event itself. might need use
meteor.settimeout
.
placing transition in rendered
might not best option happen every time template renders. instance if name
changes. think happen when code gets longer...
Comments
Post a Comment