我在流星应用中有以下事件处理程序:
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 ...有什么想法?
我几乎可以肯定这正在发生:
- 您更新文档。
- 您在该文档的渲染版本上更改CSS。
- 服务器接收更新(1),并将文档的新版本发送给客户端。
- 文档(或可能更多的东西)在您的页面上再次渲染。
问题是(4)由于从页面中删除了DOM元素并添加了新版本,因此(2)中所做的任何更改无效。在当前版本的流星中处理此问题的最佳方法是使用存储消息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>
在大卫的观察中构建DB更新的构建导致我的模板重新渲染(我应该意识到这是流星的标准行为...)。因此,我能找到的最干净的解决方案是将相关的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;将"选定"类添加到图标元素流星不会重新渲染它,并且保留了我选择的元素CSS
另一种方法是从事件处理程序中取出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过渡。但是,您避免了恒定块,这可能会在某些用例中引起问题