Ruby on Rails重定向以查看成功的AJAX加载以实现慢速控制器操作

时间:2015-09-30 11:53:02

标签: jquery ruby-on-rails ajax redirect spinner

在Ruby on Rails中,在等待慢速控制器操作时呈现AJAX“微调器”的正确方法是什么,然后在完成后重定向到正确的视图?

考虑下面的尝试:

控制器

# app/assets/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController

    def index
    end

    def slow_action
        sleep 3 # Take a nap
        respond_to do |format|
            format.js {render js: "window.location = '#{slow_action_path}';"}
            format.html {}
        end
    end
end

使用jQuery呈现微调器div的索引页面:

<!-- app/views/static_pages/index.html.erb -->
<h1>Index Page</h1>

<li><%= link_to "A link to the slow action", slow_action_path, :remote => true %></li>

<div id="spinner">
    <p>Loading... please be patient.</p>
</div>

<script type="text/javascript">
    $("#spinner").hide(); // Hide the spinner initially

    $(document).ajaxSend(function(r, s) {
        $("#spinner").show();
    });


    $(document).ajaxStop(function(r, s) {
        $("#spinner").fadeOut("fast");
    });
</script>

而且,对于它的价值,slow_action的观点是:

<!-- app/views/static_pages/slow_action.html.erb -->
<h1>This is the slow action</h1>

问题(我认为)是window.location调用只是再次调用相同的操作,服务器再次进入休眠状态。实现这个的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

我们使用spawn又称spawnling - https://github.com/tra/spawnling

你产生一个线程来处理缓慢的东西,然后重定向到另一个动作/模板,定期检查它是否已经完成。此模板显示在模式样式框中,该框悬停在页面上。我们通过创建临时文件来测试应用程序是否已完成,并跟踪生成的线程的pid,但如果您愿意,可以使用数据库。

您的问题是您在同一个地方尝试做事查看事情是否已完成。您应该有一个不同的通用操作来查看任务是否已完成,这需要一些参数来测试任务是否已完成。

答案 1 :(得分:0)

解决方案实际上非常简单。我只是以正常方式加载链接(没有:remote => true),只需要一段jQuery代码,在点击链接时在index页面上显示微调器。

控制器更简单:

# app/assets/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController

    def index
    end

    def slow_action
        sleep 3 # Take a nap before rendering the view
    end
end

索引页面变为:

<!-- app/views/static_pages/index.html.erb -->
<h1>Index Page</h1>

<div id="the-menu">
    <li><%= link_to "A link to the slow action", slow_action_path, :id => "slow-link" %></li>
</div>

<div id="spinner">
    <p>Loading... please be patient</p>
</div>

<script type="text/javascript">
    $("#spinner").hide(); // Hide the spinner by default
    $("#the-menu").show(); // But show the menu

    $("#slow-link").click(function (event) {
        console.log("onClickEvent() called")
        $("#spinner").show();
        $("#the-menu").hide();
    });
</script>

请注意,链接分配了一个id(slow-link),页面底部的jQuery定义了该链接的click事件。