【发布时间】:2015-01-12 16:42:35
【问题描述】:
我正在尝试以http://differential.com/blog/sortable-lists-in-meteor-using-jquery-ui 中描述的方式使用 JQuery-UI 实现可排序的对象列表。
但是,我不是对单独文档的列表进行排序,而是对嵌入单个文档中的对象列表进行排序。也就是说,我有一个这样的文件:
{ name: "Name of this Rolodex",
cards: [{name: "...", rank: 0, id: "some-unique-id"},
{name: "...", rank: 1, id: "some-other-unique-id"}, ... ]
}
我只想让卡片可排序。我的模板如下——它传递了一个 Rolodex 作为上下文:
<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 会更新为卡片处于新的错误位置。但是服务器存储了正确的排名,刷新页面会导致卡片列在正确的位置(至少在尝试另一种排序之前)。
我对正在发生的事情的最佳猜测是 Meteor 的模板系统似乎不理解 JQuery-UI 已经移动了 DOM 元素并以错误的顺序响应性地更新了我的模板。
例如,假设我的牌是:A、B、C。我移动 C 使得我们现在有 C、A、B。JQuery-UI 相应地更新 DOM 并触发一个事件,导致 C 的排名更改为小于A。
然而,Meteor 并不知道 DOM 已经被 JQuery-UI 改变了。但是,它确实看到了等级到 C 的变化,并根据先前关于列表顺序的假设来反应地更新列表的顺序。在这种情况下,我们最终得到 B、C、A。
关于我在这里做错了什么有什么建议吗?
【问题讨论】:
标签: javascript jquery-ui meteor meteor-blaze