Rails 5 , waiting/loading 屏幕直到模型准备就绪
Rails 5 , waiting/loading screen until Model is ready
我搜索并看到有一些答案,但大多数都太旧或似乎不合适。
这是我的流程:
(1) 用户提交表单。
(2) Controller发送DelayedJob.
(3)作业结束时Model属性状态为"Done".
我想要的是向用户显示一个 loading/waiting 屏幕,直到状态为 "Done"。
目前我以一种非常丑陋的方式做到了这一点,使用纯 JS 并重新加载页面,检查状态并在状态不是 "Done" 时显示等待动画。
但是这会导致多次访问数据库、路由器,用户在重新加载时看到页面跳转。
我正在考虑使用 respond_to JS,但我不确定该怎么做。
使用普通 javascript(jquery) 并发送 ajax get 请求来检查作业的状态。为此创建一个特殊的 action/controler(例如 jobs#status 或 job_statuses#show)。作业完成后重新加载页面或仅更新内容。
您也可以使用网络套接字来避免发送多个请求。
@Alex Kojin
@Sergio Tulentsev
它有点难看,但它确实有效(希望我在复制名称并将名称更改为更通用的名称时没有搞砸任何事情)。
config/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 %>
我搜索并看到有一些答案,但大多数都太旧或似乎不合适。
这是我的流程:
(1) 用户提交表单。
(2) Controller发送DelayedJob.
(3)作业结束时Model属性状态为"Done".
我想要的是向用户显示一个 loading/waiting 屏幕,直到状态为 "Done"。
目前我以一种非常丑陋的方式做到了这一点,使用纯 JS 并重新加载页面,检查状态并在状态不是 "Done" 时显示等待动画。
但是这会导致多次访问数据库、路由器,用户在重新加载时看到页面跳转。
我正在考虑使用 respond_to JS,但我不确定该怎么做。
使用普通 javascript(jquery) 并发送 ajax get 请求来检查作业的状态。为此创建一个特殊的 action/controler(例如 jobs#status 或 job_statuses#show)。作业完成后重新加载页面或仅更新内容。
您也可以使用网络套接字来避免发送多个请求。
@Alex Kojin @Sergio Tulentsev
它有点难看,但它确实有效(希望我在复制名称并将名称更改为更通用的名称时没有搞砸任何事情)。
config/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 %>