在Rails中,Ajax排序无法进行排序。跟上用户在我的列表中移动项目

时间:2016-07-30 12:43:25

标签: jquery ruby-on-rails ruby ajax sorting

在我的rails应用程序中,我创建了一个列表,允许用户通过单击/拖放它们来重新排序记录。每次重新订购后,我都会运行更新操作并传递已移动项目的public class AjaxImage extends MNServlet { private static URLCodec urlcodec = new URLCodec("UTF-8"); private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { boolean isMultipart = ServletFileUpload.isMultipartContent(request); String id = request.getParameter(Plugin.PLUGIN_ID_VARIABLE); if (isMultipart) { FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); try { List<FileItem> multiparts = upload.parseRequest(request); for (FileItem item : multiparts) { if (!item.isFormField()) { String road = ""; try { String name = new File(item.getName()).getName(); String relativeWebPath = "/image"; String absoluteFilePath = request.getServletContext().getRealPath(relativeWebPath); item.write(new File(absoluteFilePath, FilenameUtils.getName(item.getName()))); request.setCharacterEncoding("UTF-8"); String data = ""; try { data =urlcodec.decode(request.getParameter("data"), "UTF-8"); } catch (DecoderException e) { e.printStackTrace(); } } catch (Exception e) {} } } } catch (Exception e) { e.printStackTrace(); } } } } old_index,并重新排序整个列表。只要我不以非常快的速度重新排序项目,该应用程序就可以正常运行。我的问题是如何改进设计,我必须考虑用户快速排序并准确反映这些变化?此外,我试图阻止用户点击&#34;保存&#34;按钮 - 但如果有必要,那么我可以实现它。

更新操作

new_index

我也使用以下gem: https://github.com/scttdavs/sortable-rails

1 个答案:

答案 0 :(得分:0)

您的代码可以进行一些改进,但它们无法解决后端的root问题,无法跟上UI更新。

当您执行多个数据库请求时,这些请求需要将数据保持在一致状态,这应该在事务中完成:

if @list_item.present?
  # update the modified item, and then update all items after that are affected
  old_index = params[:old_rank].to_i
  new_index = params[:sequence_rank].to_i

  @list_item.transaction do
    @list_item.update(sequence_rank: new_index)

    if old_index < new_index
      ...
    end
  end
end

这段代码

.each_with_index do |item, index|
  item.update(sequence_rank: item.sequence_rank - 1)

比它慢。这是因为each_with_index必须从数据库中获取记录并将它们包装在ActiveRecord模型类中。然后item.update为每条记录调用一个单独的SQL语句。一种改进方法是发出单个原始SQL更新语句,减少所有受影响记录的sequence_rank

sql = "UPDATE list_items SET sequence_rank = sequence_rank - 1 WHERE ..."
@list_item.connection.execute(sql)

递增sequence_rank的查询可能与上面的内容合并。

解决根本问题,至少有两种解决方案。一种是禁用列表UI,直到更新ajax请求返回。这样您可以确保更新是串行的。但它有一些可用性影响。

另一种方法是在前端累积更新并按间隔或其他一些事件保存它们,同样,在ajax调用期间禁用相关的UI。这实现起来更复杂,但可能对可用性的影响较小。