2017-03-04 71 views
0

我搜索並看到有一些答案,但大多數都很舊或似乎不足。Rails 5,等待/加載屏幕,直到模型準備好

這是我的流程:
(1)用戶提交表單。 (2)控制器發送DelayedJob。 (3)在作業結束時,模型屬性狀態爲「完成」。

我想要的是向用戶顯示加載/等待屏幕,直到狀態爲「完成」。

此刻我以非常醜陋的方式做了這個,使用純JS和重新加載頁面,檢查狀態並顯示等待的動畫,而狀態不是「完成」。

但是這會導致對數據庫,路由器的多次訪問,並且用戶在重新加載時會看到頁面跳轉。

我想使用respond_to JS,但我不知道該怎麼做。

回答

1

使用普通的javascript(jquery)併發送ajax get請求來檢查作業的狀態。爲此創建一個特殊的操作/控制器(例如作業#status或job_statuses#show)。重新加載頁面或僅在作業完成後更新內容。

您也可以使用網絡套接字不發送多個請求。

+0

「check_job_statuses#秀」 - 沒了!更好的「job_statuses#show」:) –

+0

這就是我認爲,一旦實施,我會發布我是如何做到的,並將答案標記爲已接受。謝謝。 (我希望有更多'Rails的方式'來做到這一點,哦) –

+0

@SergioTulentsev你完全正確。只是想提出一個服務控制器,它應該使用'create'方法 - 「check_job_statuses#create」 –

0

@Alex荒神 @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 %>