在Rails中创建可拖动可排序列表的最有效方法是什么?

时间:2015-07-10 01:32:56

标签: ruby-on-rails ruby ruby-on-rails-4

我想创建可拖动的有序列表但是根据this blog,acts_as_lists gem是服务器密集型的,它还说构建失败。他们建议排名模型宝石,但它似乎已被弃用。

当有许多用户重新安排列表时,最有效的方法是在不造成服务器上的巨大负载的情况下执行此操作。

1 个答案:

答案 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'>&nbsp;&nbsp;&nbsp;</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进行转换。