我搜索并看到有一些答案,但大多数都很老或看似不合适。
这是我的流程:
(1)用户提交表格
(2)控制器发送DelayedJob
(3)在作业结束时,模型属性状态为"完成"。
我想要的是向用户显示加载/等待屏幕,直到状态为"完成"。
目前我以一种非常丑陋的方式做到了这一点,使用普通的JS并重新加载页面,检查状态并显示等待的动画,而状态不是"完成"。
但这导致对数据库,路由器和用户的多次访问在重新加载时看到页面跳转。
我在考虑使用respond_to JS,但我不知道该怎么做。
答案 0 :(得分:1)
使用普通的javascript(jquery)并发送ajax get请求来检查作业的状态。为此创建特殊的动作/控制器(例如jobs#status或job_statuses #show)。重新加载页面或仅在作业完成后更新内容。
您也可以使用网络套接字发送多个请求。
答案 1 :(得分:0)
@Alex Kojin @Sergio Tulentsev
它有点难看,但它有效(希望我在复制和更改名称时更加通用的东西时没有搞砸任何东西)。
<强> 配置/ routes.rb中: 强>
get 'loading_screen/:id' , to: 'model_name#loading_screen' , as: 'loading_screen'
match 'loading_status' , to: 'model_name#loading_status' , as: 'loading_status' , :via => [:get,:post]
在model_name控制器中:
def loading_screen
@model_name = ModelName.find_by(id: params.try(:fetch,:id,nil))
@id = @model_name.try(:id)
end
def loading_status
@model_name = ModelName.find_by(id: params.try(:fetch,:id,nil)
@id = @model_name.try(:id)
@json = { status: @model_name.try(:status) , id: @id }.to_json
respond_to do |format|
format.js do
render layout: false
end
end
end
观看loading_screen.html.erb:
<script>
function checkStatus( id ) {
$.ajax({
url: '/loading_status',
data: { id: id } ,
dataType: 'json',
success: function(res) {
var status = res.status;
var id = res.id;
console.log("json = " + JSON.stringify(res,null,2) );
if ( status == "Done" ) {
window.location = "/path_to_view_completed_results/" + id;
myStopFunction();
} else if ( count > 30 ) {
myStopFunction();
}
}
});
}
var id = <%= @id %> ;
var count = 0;
var myInterval = setInterval(function(){ checkStatus( id ) }, 1000);
function myStopFunction() { clearInterval(myInterval); }
</script>
在loading_status.js.erb中:
<%= @json.html_safe %>