我在Meteor应用程序中有以下事件处理程序:
Template.messageItem.events({
'click .message-block #faveMsg': function (e) {
console.log($(e.target));
if (_.contains(this.favoritedBy, Meteor.userId())) {
Messages.update({_id: this._id}, {$pull: {favoritedBy: Meteor.userId()} });
$(e.target).removeClass('selected');
} else{
Messages.update({_id: this._id}, {$addToSet: {favoritedBy: Meteor.userId() } });
$(e.target).addClass('selected');
};
console.log(this.favoritedBy);
// $(e.target).toggleClass('selected');
}
});
CSS更新独立运作。一旦我引入db逻辑,CSS更改就会停止工作。
我之前有一个toggleClass方法(上面已注释掉)完成了这项工作,但是如果我在注释掉当前正在使用的添加/删除方法时恢复它就不再有用了...即我添加了数据库后出现问题逻辑。
我猜这是一个愚蠢的JS语法问题,因为我是js newb ...任何想法?
答案 0 :(得分:1)
我几乎可以肯定这种情况正在发生:
问题是(4)使(2)中所做的任何更改无效,因为DOM元素已从页面中删除,并且添加了新版本。在当前版本的流星中处理此问题的最佳方法是使用存储消息ID的会话变量。然后,您可以使用该会话变量来呈现正确的css版本。因此,您可以执行以下$(e.target)...
代替:
Session.set('selectedMessage', this._id);
然后你可以像这样添加一个模板助手:
Template.messageItem.helpers({
selected: function() {
return Session.equals('selectedMessage', this._id);
}
});
最后,您的模板代码可以使用该帮助程序来显示正确的类:
<div class='{{selected}}'>{{message.text}}</div>
答案 1 :(得分:0)
基于David观察上面的数据库更新导致我的模板重新渲染(我应该意识到这是Meteor中的标准行为......)。因此,我能找到的最干净的解决方案是将相关的HTML元素包装在一个常量块中:
<span class="speech-left-title">
{{#constant}}
<i id="faveMsg" class="fa fa-star"></i>
{{/constant}}
Received from {{sentBy}} {{timeago sentTime}}.
</span>
{{#if msgTypeText}}
<p class="speech-left blue-bubble">{{msgText}}</p>
...
随后当我的JS功能更新DB&amp;将“selected”类添加到图标元素Meteor不会重新渲染它并保留我的selected元素CSS
答案 2 :(得分:0)
另一种方法是从事件处理程序中取出CSS类插入并将条件逻辑放在html / handlebars代码中:
<span class="speech-left-title">
{{#if favoritedByMe}}
<i id="faveMsg" class="fa fa-star selected"></i>
{{else}}
<i id="faveMsg" class="fa fa-star"></i>
{{/if}}
Received from {{sentBy}} {{timeago sentTime}}.
</span>
这会对元素进行反应性更新并且运行良好。这种方法的缺点是它只是在它被收藏时重新渲染html图标元素而不是仅添加一个类,因此你会失去CSS过渡。但是,您可以避免在某些用例中可能导致问题的常量块