在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
调用只是再次调用相同的操作,服务器再次进入休眠状态。实现这个的正确方法是什么?
答案 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
事件。