我有一个 Backbone.js 集合,我希望能够使用 jQuery UI 的 Sortable 对其进行排序。没什么特别的,我只是有一个我希望能够排序的列表。
问题是我不确定如何在排序后获取项目的当前顺序并将其传达给集合。 Sortable 可以自行序列化,但这不会为我提供我需要提供给集合的模型数据。
理想情况下,我希望能够只获取集合中模型当前顺序的数组,并对集合使用重置方法,但我不确定如何获取当前顺序。请分享有关获取当前模型订单数组的任何想法或示例。
最佳答案
我通过使用 jQuery UI Sortable 在项目被放下时触发项目 View 上的事件来完成此操作。然后我可以在项目 View 上触发另一个事件,该事件包括模型作为 Collection View 绑定(bind)到的数据。然后 Collection View 可以负责更新排序顺序。
工作示例
http://jsfiddle.net/7X4PX/260/
jQuery UI 可排序
$(document).ready(function() {
$('#collection-view').sortable({
// consider using update instead of stop
stop: function(event, ui) {
ui.item.trigger('drop', ui.item.index());
}
});
});
stop事件绑定(bind)到一个函数,该函数触发 DOM 节点上的 drop
,并将项目的索引(由 jQuery UI 提供)作为数据。
项目 View
Application.View.Item = Backbone.View.extend({
tagName: 'li',
className: 'item-view',
events: {
'drop' : 'drop'
},
drop: function(event, index) {
this.$el.trigger('update-sort', [this.model, index]);
},
render: function() {
$(this.el).html(this.model.get('name') + ' (' + this.model.get('id') + ')');
return this;
}
});
drop 事件绑定(bind)到 drop
函数,该函数在带有数据 [this.model,索引]
。这意味着我们正在将当前模型及其索引(来自 jQuery UI 可排序)传递给绑定(bind)到 update-sort
事件的任何人。
项目(集合) View
Application.View.Items = Backbone.View.extend({
events: {
'update-sort': 'updateSort'
},
render: function() {
this.$el.children().remove();
this.collection.each(this.appendModelView, this);
return this;
},
appendModelView: function(model) {
var el = new Application.View.Item({model: model}).render().el;
this.$el.append(el);
},
updateSort: function(event, model, position) {
this.collection.remove(model);
this.collection.each(function (model, index) {
var ordinal = index;
if (index >= position) {
ordinal += 1;
}
model.set('ordinal', ordinal);
});
model.set('ordinal', position);
this.collection.add(model, {at: position});
// to update ordinals on server:
var ids = this.collection.pluck('id');
$('#post-data').html('post ids to server: ' + ids.join(', '));
this.render();
}
});
Items
View 绑定(bind)到 update-sort
事件,函数使用事件传递的数据(模型和索引)。模型从集合中移除,ordinal
属性在每个剩余项目上更新,项目按 id 的顺序发送到服务器以存储状态。
收藏
Application.Collection.Items = Backbone.Collection.extend({
model: Application.Model.Item,
comparator: function(model) {
return model.get('ordinal');
},
});
该集合有一个 comparator定义的函数,它按 ordinal
对集合进行排序。这使项目的呈现顺序保持同步,因为集合的“默认顺序”现在由 ordinal
属性的值决定。
请注意,存在一些重复工作:如果集合像 jsfiddle 那样具有比较器函数,则不需要删除模型并将其添加回集合。此外, View 可能不需要重新呈现。
注意:与其他答案相比,我的感觉是通知项目的模型实例需要更新而不是直接通知集合更正确。这两种方法都是有效的。这里的另一个答案直接进入集合,而不是采用模型优先的方法。选择对您来说更有意义的那个。
关于javascript - 将 jQuery UI Sortable 的顺序保存到 Backbone.js 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10147969/