【问题标题】:Rails 5 , waiting/loading screen until Model is readyRails 5,等待/加载屏幕,直到模型准备好
【发布时间】:2017-03-05 02:22:00
【问题描述】:

我搜索并看到有一些答案,但大多数都非常陈旧或似乎不足。

这是我的流程:
(1) 用户提交表单。
(2) Controller 发送一个DelayedJob。
(3) 作业结束时,模型属性状态为“完成”。

我想要向用户显示加载/等待屏幕,直到状态为“完成”。

目前我以一种非常丑陋的方式做到了这一点,使用纯 JS 并重新加载页面,检查状态并在状态不是“完成”时显示等待动画。

但这会导致对 DB 、 router 的多次访问,并且用户在重新加载时会看到页面跳转。

我正在考虑使用 respond_to JS,但我不知道该怎么做。

【问题讨论】:

    标签: javascript jquery ruby-on-rails ruby spinner


    【解决方案1】:

    使用纯 javascript(jquery) 并发送 ajax get 请求来检查作业的状态。为此创建特殊的操作/控制器(例如 jobs#status 或 job_statuses#show)。作业完成后重新加载页面或更新内容。

    您也可以使用网络套接字不发送多个请求。

    【讨论】:

    • "check_job_statuses#show" - 不!更好的“job_statuses#show”:)
    • 这就是我的想法,一旦实施,我将发布我是如何做到的,并将答案标记为已接受。谢谢。 (我希望有更多的“Rails 方式”来做到这一点,哦,好吧)
    • @SergioTulentsev 你说得对。只是想提出一个服务控制器,它应该使用create方法-“check_job_statuses#create”
    • 解决方案已发布,已标记答案以及对我的代码的任何改进。
    【解决方案2】:

    @亚历克斯·科金 @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 %>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-04
      • 2019-01-23
      • 1970-01-01
      • 2013-01-26
      • 2010-10-22
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      相关资源
      最近更新 更多