流.js.erb响应

时间:2018-07-29 22:49:01

标签: ruby-on-rails

在这种情况下,当用户提交表单时, $("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]);

我可以做这项工作吗,或者如果可以的话,我应该看看对此可行吗?

1 个答案:

答案 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>