jQuery-UI可排序列表与Meteor模板中的反应式更新不兼容 [英] Jquery-UI sortable list not playing nice with reactive updates in Meteor template

查看:106
本文介绍了jQuery-UI可排序列表与Meteor模板中的反应式更新不兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用但是,我不是对单独的文档列表进行排序,而是对嵌入在单个文档中的对象列表进行排序.也就是说,我有一个像这样的文件:

However, rather than sort a list of separate documents, I'm sorting a list of objects embedded within a single document. That is, I have a document like so:

{  name: "Name of this Rolodex",
   cards: [{name: "...", rank: 0, id: "some-unique-id"},
           {name: "...", rank: 1, id: "some-other-unique-id"}, ... ]
}

我只想对卡片进行分类.我的模板如下-它传递了一个Rolodex作为上下文:

And I just want to make the cards sortable. My template is as follows -- it's passed a single Rolodex as the context:

<template name="rolodex">
  Rolodex Name: {{name}}
  <div class="cards-list">
    {{#each sortedCards}}
      {{> cardTemplate}}
    {{/each}}
  </div>
</template>

和辅助JS文件:

Template.rolodex.helpers({
  sortedCards: function() {
    return this.cards.sort(function(cardA, cardB) {
      return cardA.rank - cardB.rank;
    });
  }
});

Template.rolodex.rendered = function() {
  this.$(".cards-list").sortable({
    stop: function(e, ui) {
      // Get dragged HTML element and one immediately before / after
      var el = ui.item.get(0)
      var before = ui.item.prev().get(0)
      var after = ui.item.next().get(0)

      // Calculate new rank based on ranks of items before / after
      var newRank;
      if(!before) {
        // First position => set rank to be less than card immediately after
        newRank = Blaze.getData(after).rank - 1;
      } else if(!after) {
        // Last position => set rank to be more than card immediately after
        newRank = Blaze.getData(before).rank + 1;
      } else {
        // Average before and after
        newRank = (Blaze.getData(after).rank + 
                   Blaze.getData(before).rank) / 2;
      }

      // Meteor method that updates an attribute for a single card in a
      // Rolodex based on IDs for the Rolodex and Card
      Meteor.call('cards/update',
                  Blaze.getData(ui.item.parent().get(0))._id, // Rolodex ID
                  Blaze.getData(el).id, // Card ID
                  {rank: newRank});
    }
  });
};

我遇到的问题是,在将卡分类到其预期位置后,DOM随即以新的错误位置更新了卡.不过,服务器存储的排名正确,刷新页面会使卡以正确的位置列出(至少直到尝试另一种排序为止).

The problem I'm running into is that after sorting a card into its expected position, the DOM is then updated with the card in a new, wrong position. The server has the correct rankings stored though, and refreshing the page causes the card to be listed in its correct position (at least until another sort is attempted).

关于发生的事情,我最好的猜测是Meteor的模板系统似乎不了解JQuery-UI已经移动了DOM元素,并以错误的顺序对我的模板进行了反应性的更新.

My best guess as to what is happening is that Meteor's templating system doesn't seem to understand that the JQuery-UI has moved the DOM elements around and is reactively updating my template in the wrong order.

例如,假设我的牌是:A,B,C.我移动C使得我们现在有了C,A,B.JQuery-UI相应地更新DOM并触发一个事件,导致C的等级更改为小于A.

For example, suppose my cards are: A, B, C. I move C such that we now have C, A, B. JQuery-UI updates the DOM accordingly and fires an event which results in C's rank being changed to be less than A's.

但是,Meteor不知道DOM已被JQuery-UI更改.但是,它的确看到了C的等级变化,并基于先前关于列表顺序的假设,以反应方式更新了列表的顺序.在这种情况下,我们以B,C,A结尾.

However, Meteor doesn't know that the DOM has already been altered by JQuery-UI. It does, however, see the change in rank to C and reactively updates the order of the list based on prior assumptions about what the list order was. In this case, we end up with B, C, A.

关于我在这里做错什么的任何建议吗?

Any suggestions as to what I'm doing wrong here?

推荐答案

Meteor/Blaze使用_id属性来标识数据对象并将其链接到DOM元素.这不仅适用于Collection游标返回的文档数组,还适用于任何对象数组.因此,在上述问题中,问题在于我使用了id值而不是_id来标识每张卡.将id切换为_id可以解决此问题,并允许Blaze正确更新DOM,即使该DOM先前已通过JQuery-UI的sortable插件进行了修改.

Meteor/Blaze uses an _id attribute to identify data objects and link them to DOM elements. This applies not only to arrays of documents returned by a Collection cursor, but to any array of objects. So in the above issue, the problem was that I used an id value to identify each card rather than _id. Switching id to _id fixes the issue and allows Blaze to properly update the DOM, even if the DOM has previously been modified by JQuery-UI's sortable plugin.

这篇关于jQuery-UI可排序列表与Meteor模板中的反应式更新不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆