在这种情况下,当用户提交表单时,
$("body .my-flash-div")
div应该首先显示
Generating report
几秒钟后
Sql executing
依此类推。
我的问题是最终用户无法立即看到结果,而不能一步一步地看到结果。这是我的设置:
End users want to download reports
Report generation is a multi step process, takes 5-10 seconds.
Step 1 user does GET /users_report/new
There's a form there, user enters email address, submits
And it's handled by
class UsersReportController < ApplicationController
def create
respond_to do |format|
format.js
end
end
# app/views/users_report/create.js.erb
$("body .my-flash-div").html("Generating report");
<% Namespace::gen_report_step_1 %>
<% sleep 1 %>
$("body .my-flash-div").html("Sql executing");
<% Namespace::gen_report_step_2 %>
<% sleep 1 %>
$("body .my-flash-div").html("Post processing");
<% Namespace::gen_report_step_3 %>
<% sleep 1 %>
$("body .my-flash-div").html("gzip execute");
<% Namespace::gen_report_step_4 %>
<% sleep 1 %>
$("body .my-flash-div").html("Emailing "+params[:email]);
我可以做这项工作吗,或者如果可以的话,我应该看看对此可行吗?
答案 0 :(得分:0)
要做类似的事情,我使用了提到的Thread技术。
https://solidfoundationwebdev.com/blog/posts/how-to-perform-some-task-after-view-render-using-threads-in-rails
。
这篇有关如何使用ActionCable https://github.com/wintermeyer/rails-5.2-book/blob/master/action-cable.adoc
# in controller
def create
respond_to do |format|
format.js
end
Thread.new do
send_report(params[:email], "web_notifications_#{params[:async_response_guid]}")
Thread.exit
end
end
# inside send_report() method
...
ActionCable.server.broadcast(logger, msg: "Generating.")
...
# inside app/views/users_report/_form.html.erb
<% async_response_guid ||= SecureRandom.hex[0..6] %>
<script>
(function() {
App.room = App.cable.subscriptions.create({
channel: "WebNotificationsChannel",
room: "<%= async_response_guid %>"
}, {
received: function(data) {
$(".output-<%=async_response_guid%>").html(data.msg);
return console.log("here1 " + data.msg);
}
});
}).call(this);
</script>
<span class="badge badge-pill badge-light form-flash output-<%=async_response_guid%>"></span>