我有一些问题弄清楚如何Meteor.rendered
工作。我正在尝试为 Meteor 中的实时变化设置动画,就像这个问题一样。每当我点击一个元素时,我希望它闪烁。
但是,每次单击元素时,模板都会被渲染两次,这反过来又会触发两次动画。这是代码:
模板
<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();
};
我的理解是,每次Session.set
调用时,都会Session.get
重新运行用于相同键的每个模板,如文档中所述。所以我的猜测是,不知何故,Session.equals
可能会导致模板重新运行 2 次?如果我使用此代码更改selected
助手:
Template.myItem.helpers({
selected: function () {
if (Session.get("selected")) === this._id)
return "selected";
else
return "";
}
});
然后动画被触发 3 次而不是 2 次。
考虑到所有这些,我的问题是:
- 为什么会
Template.myItem.rendered
被触发两次?幕后究竟发生了什么? - 我怎样才能解决这个问题,让我的动画只触发一次?
回答详情
所以评论@Xyand解决方案:
- 将动画移动到
click
事件中Meteor.setTimeout()
绝对有效,但对我来说有点hacky。 解决方案实际上非常简单,并且已经在这个问题中给出。代码如下所示:
Template.myItem.rendered = function () { if (Session.equals('selected', this.data._id)) $(this.firstNode).fadeOut().fadeIn(); };
我首先在一个具有不同模板标记的不同项目上进行了尝试,但它不起作用,这就是我创建这个最小项目以查看哪里出了问题的原因。事实证明,要使其正常工作,您绝对需要在模板myItem
内调用一个子myItemList
模板。如果模板看起来像这样,
<template name="myItemList">
{{#each items}}
<div class="item {{selected}}">
<h4>{{name}}</h4>
<p>{{description}}</p>
</div>
{{/each}}
</template>
因此rendered
为myItemList
模板调用每个帮助函数和函数,代码将不起作用,因为在rendered
函数内部,模板实例将具有.data
未定义的属性。