如何使用Javascript或Ruby on Rails实现网页自动刷新

3
我想让我的页面在通过JavaScript或Ruby on Rails代码排序新位置后重新加载。
$("#serialize").click ->
c = set: JSON.stringify($("#sortable").nestedSortable("toHierarchy",
  startDepthCount: 0
))
$.post "savesort", c, $("#output").html("<p id=\"flash_notice\">Saved Successfully</p>")
false

我考虑将它添加到这里。
$.post "savesort", c, $("#output").html("<p id=\"flash_notice\">Saved Successfully</p>")
window.location.reload(false); 
false

但是这样似乎会搞乱顺序。以下是我的Rails代码:

class SiteController < ApplicationController

def savesort
neworder = JSON.parse(params[:set])
prev_item = nil
neworder.each do |item|
  dbitem = Category.find(item['id'])
  prev_item.nil? ? dbitem.move_to_root : dbitem.move_to_right_of(prev_item)
  sort_children(item, dbitem) unless item['children'].nil?
  prev_item = dbitem   
end
Category.rebuild!
render :nothing => true
  end
end

我还在考虑将render :nothing => true更改为redirect_to root_url,但似乎也不起作用。

这是我的Routes.rb(由于篇幅缘故进行了缩短)

locksmithing::Application.routes.draw do
  get "site/home"
  match "/savesort" => 'site#savesort'
    root to: 'site#home'
end

那么,我应该在哪里添加代码才能刷新页面?是在JavaScript中还是在站点控制器中?或者有其他解决方案吗?提前感谢。

2个回答

4

首先,你的$.post调用并不会像你期望的那样起作用。下面这段代码:

$.post "savesort", c, $("#output").html("<p id=\"flash_notice\">Saved Successfully</p>")

与以下内容相同:

$.post "savesort", c

我认为你的意图是在异步的$.post调用完成后执行$('#output').html(),但你需要一个回调函数来实现这一点。你需要在$.post的这部分代码中添加一个回调函数:

$("#output").html("<p id=\"flash_notice\">Saved Successfully</p>")

当进行$.post调用构建时,将执行该回调函数,它的返回值将是一个jQuery对象,$.post不知道如何处理它。为了解决这个问题,只需将回调函数包装在另一个回调函数中:

$.post "savesort", c, ->
    $("#output").html("<p id=\"flash_notice\">Saved Successfully</p>")

如果您在$.post之后立即放置window.location.reload(false),那么您将在POST完成之前重新加载页面,这可能不是您想要做的,并且这就解释了您的“顺序混乱”问题。尝试将其移动到$.post回调中,以便它会在POST完成后执行:

$.post "savesort", c, ->
    $("#output").html("<p id=\"flash_notice\">Saved Successfully</p>")
    window.location.reload(false)

您原来的代码完全忽略了SiteController#savesort的响应,因此它返回什么都无所谓。上述回调变化仍然忽略控制器返回的内容,但这没关系,:nothing => true是一个明智的选择。

一旦您完成所有这些工作,您可以通过让控制器返回要插入页面的新数据来替换重新加载,然后$.post回调可以将该新数据插入页面。这将是一种相当标准的AJAX方法。


那是一些很好的信息,我能够跟随您的解决方案并且它起作用了。非常感谢,我是Javascript/Jquery/Coffeescript的新手,所以在将其从Javascript转换为Coffeescript时可能出现了问题。我已经让它工作了,并将尝试您提到的AJAX方法。 - ruevaughn

2

当您向服务器post时,您的服务器可以发送一个小部分,仅重新渲染更改的页面部分。

调整您的控制器操作,不声明任何渲染/重定向操作:

class SiteController < ApplicationController

  def savesort
    neworder = JSON.parse(params[:set])
    prev_item = nil
    neworder.each do |item|
      dbitem = Category.find(item['id'])
      prev_item.nil? ? dbitem.move_to_root : dbitem.move_to_right_of(prev_item)
      sort_children(item, dbitem) unless item['children'].nil?
      prev_item = dbitem   
    end
    Category.rebuild!
  end
end

现在,它将查找名为savesort.js.erb的默认视图。在该视图中,您可以执行任何操作来覆盖类别列表。

此文件包含在浏览器中执行的纯JavaScript,因此例如:

$("#output").html("<p id=\"flash_notice\">Saved Successfully</p>")

当然,你还希望它能更新屏幕上更相关的部分。
这是迄今为止最理想的方法。它只会对屏幕进行部分更新,并且会给用户最快的响应感受。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接