我想创建可拖动的有序列表但是根据this blog,acts_as_lists gem是服务器密集型的,它还说构建失败。他们建议排名模型宝石,但它似乎已被弃用。
当有许多用户重新安排列表时,最有效的方法是在不造成服务器上的巨大负载的情况下执行此操作。
答案 0 :(得分:7)
我使用HTML5 Sortable jQuery Plugin。
对于每个项目,都有一个排序字段来指定排序(1到n)。一旦用户完成了可拖动排序,则将排序发布到阵列中的Rails后端,例如, [1,5,3,6,2,4]。数组中的数字是项目的 id 。基于此数组,我可以更新排序字段。例如,数组中的第一项(id = 1)具有排序1,第二项(id = 5)具有排序2.稍后,您可以使用订单(“订购ASC”)进行排序
首先,有一个排序视图(路径为获取'项目/排序')供用户进行可拖动排序。它看起来像这样(纤细的格式):
div#items-sortable
- @items.each do |item|
= div_for item, data: {id: item.id}
= item.title
hr
= form_tag action: :ordering do
= hidden_field_tag :items_ids, ""
= submit_tag 'Save Changes'
表单是保留排序数组并允许将数据发布到Rails。
Javascript(CoffeeScript)如下所示:
sortable_element = document.getElementById('items-sortable')
if sortable_element
$(sortable_element).sortable({
placeholder: "<div style='border-style: dashed'> </div>"
})
.bind('sortupdate', (e, ui) ->
orders = ui.endparent.children().map( -> return $(this).data("id") ).toArray()
document.getElementById('items_ids').value = JSON.stringify(orders)
)
当用户进行排序时,它会通过项目ID的排序来更新表单的隐藏字段。
排序完成后,用户点击“保存更改”按钮,会将其发布到使用 item_ids 参数路由项目/订购。控制器中的方法如下所示:
def ordering
if (@orders = params[:items_ids]) && (@orders.present?)
@orders = JSON.parse(params[:items_ids])
if @orders.kind_of?(Array) && @orders.size > 0
# Let build hash for mass update
data = {}
@orders.each_with_index do |iden, index|
data[iden] = {ordering: index}
end
Item.all.update(data.keys, data.values) # still update one-by-one at backend
end
end
respond_to do |format|
format.html { redirect_to items_path }
end
end
如果您不想使用表单,可以尝试使用AJAX进行转换。