Meteor.js事件处理程序:DB & CSS 问题



我在流星应用中有以下事件处理程序:

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 ...有什么想法?

我几乎可以肯定这正在发生:

  1. 您更新文档。
  2. 您在该文档的渲染版本上更改CSS。
  3. 服务器接收更新(1),并将文档的新版本发送给客户端。
  4. 文档(或可能更多的东西)在您的页面上再次渲染。

问题是(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过渡。但是,您避免了恒定块,这可能会在某些用例中引起问题

最新更新