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

Javascript Meteor.js事件处理程序:DB&;CSS问题,javascript,jquery,meteor,Javascript,Jquery,Meteor,我在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应用程序中有以下事件处理程序:

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新手。。。有什么想法吗?

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

  • 您可以更新文档
  • 您可以更改该文档的呈现版本上的css
  • 服务器接收更新(1),并向客户端发送文档的新版本
  • 文档(或可能更多内容)将再次呈现在页面上
  • 问题在于(4)会使(2)中所做的任何更改无效,因为DOM元素会从页面中删除,并重新添加新版本。在当前版本的meteor中处理此问题的最佳方法是使用存储消息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>
    
    {{message.text}
    
    基于David在DB更新上面的观察,我的模板被重新渲染(我应该意识到这是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> 
      ...
    
    
    {{{#常数}}
    {{/常数}
    从{{sentBy}{{timeago sentTime}收到。
    {{#如果msgTypeText}}
    

    {{msgText}}

    ...

    随后,当my JS函数更新DB&将“selected”类添加到图标元素Meteor不会重新渲染它,它会保留我的selected元素CSS

    另一种方法是从事件处理程序中取出CSS类插入,并将条件逻辑放入html/Handlebar代码中:

      <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>
    
    
    {{{#如果有偏爱的话}
    {{else}
    {{/if}
    从{{sentBy}{{timeago sentTime}收到。
    

    这会反应性地更新元素,并且效果良好。这种方法的缺点是,它只是在喜欢html图标元素时重新呈现该元素,而不仅仅是添加一个类,因此会丢失CSS转换。但是,您避免了在某些用例中可能导致问题的持续阻塞

    谢谢David!我认为你的重新渲染造成了问题,这是一针见血。我没有使用会话变量&helper方法,而是通过在HTMLYep中指定一个#常量区域来解决它,这看起来不错。从这个问题中,我没有意识到您正在更新的元素没有任何绑定,因此可以设置为常量。我怀疑当渲染引擎的新版本发布时(应该是0.8版本),我认为这一步是不必要的。