2017-07-07 18 views
0

我有一個基本的表單,當提交時,觸發一個創建請求到外部API。在提交時,會出現一個包含進度條的階段值,而不是提交按鈕。創建過程需要花費時間在外部API上,因此我必須每秒使用while status == 'inactive'運行一些Show請求,並在顯示請求響應爲status: 'active'時停止。 每個Show請求響應還包含一個'stage'屬性,該屬性顯示創建過程的階段(連接,創建,獲取,整理等)。對於每個請求,當前階段都存儲在@stage變量中,可以使用ApiRequest.stage訪問該變量。每個API相關的東西都在一個服務文件中。Rails - 用動態變量修改%p的文本

我的CoffeeScript與舞臺+進度條更改提交按鈕:

$('#new_connection').on 'submit', -> 
    button = $('#submit_button') 
    progress = $('.loading') 
    button.fadeOut 500 
    setTimeout (-> 
     if button.is(':hidden') 
     progress.fadeIn 500 
     return 
    ), 509 
    return 

和部分舞臺+進度條:

.loading 
    %p.center-align#stage <!-- This should display the stage in real time --> 
    .progress <!-- This is a materializecss progress bar --> 
    .indeterminate 

如何更新內部#stage文字與ApiRequest.status每次實時在同一頁面上更改值時,從表單提交到結束的那一刻(當所有背景中的所有內容都完成後,它將重定向到create.html)?

回答

0

好的,你所要做的就是在控制器中創建一個讀取變量的方法:​​3210。
format.json { render json: { stage: @stage } }寫一個respond_to do |format|
現在您必須爲此自定義控制器方法創建路線:get '/your/link', to: 'controller#custom_method', as: 'stage'
所有剩下的就是通過Ajax來觸發這個方法:

$.get({ 
    url: "your/link.json", 
    success: function(data) { 
    $('#your_paragraph_id').text(data['stage]); 
    }, 
}); 

你可以把這個Ajax調用的setInterval函數。

1

實時顯示您操作的狀態,或者至少接近實時,你必須要麼

  • 調查定期服務器,看看狀態已經改變 - 那就是,保持每秒鐘或兩次觸發show端點,並更新成功回調中的狀態標籤
  • 或者您可以實現一種方案,只要狀態使用WebSocket,長輪詢或其他技術進行更改,服務器就會通知該頁面。

投票就像當你駕駛一輛汽車時,你的一位乘客不停地問:「我們到了嗎?每一秒。它不是非常有效,特別是在操作需要很長時間的情況下,因爲每隔012秒發出一個單獨的HTTP請求,只能返回一個「仍在進行中」的響應。但它很容易實現,所以如果show操作很快並且操作本身很快完成,那麼它可能是一個很好的折衷方案。

另一種方法是讓服務器在狀態更改發生時通知您。爲此,您需要有一個發佈者訂戶基礎架構。如果您使用的是Rails 5,那麼Action Cable可能是您最好的選擇,因爲它內置於Rails中。您可以在此處找到不同可用技術的詳細比較:In what situations would AJAX long/short polling be preferred over HTML5 WebSockets?

如果您正在使用輪詢,則可以將常規AJAX調用的success回調中的狀態標籤更新爲show。如果show只呈現HTML,那麼你將不得不從AJAX響應數據解析出新的狀態:在普通的JavaScript

<!-- example output of show.html.erb --> 
<!-- ... --> 
    <div id="current-status"><%= @status %></div> 
<!-- ... --> 

例在AJAX響應解析頁面並獲取#current-status<div>的價值:

setTimeout(function() { 
    $.get({ 
    url: "<%= show_page_path %>", 

    success: function(data) { 
     var response = $("<div></div>"). 
     append($.parseHTML(data, null, true)); 

     $("#current-status").html(
     $("#current-status", response) 
    ); 
    }, 
    }); 
}, 1000); 

當然,如果你添加一個JSON終點爲show動作只包括狀態:

# in the controller 
respond_to do |format| 
    format.html 
    format.json do 
    render json: { status: @status } 
    end 
end 

然後,你不必做任何HTML解析:

setTimeout(function() { 
    $.get({ 
    url: "<%= show_page_path(format: :json) %>", 

    success: function(data) { 
     $("#current-status").text(data.status); 
    }, 
    }); 
}, 1000); 

的例子是未經檢驗的,所以他們可能沒有一些修改很好地工作。

+0

在後端一切正常,我不得不每秒都會觸發'show'動作,因爲每個請求都會返回一個新的'stage'進程。雖然所有內容都在後臺運行,但用戶可通過進程欄獲取進程欄(連接,創建,獲取,整理)。隨着每一個新的請求,我更新'@舞臺'。我想在視圖中顯示「@ stage」,這樣用戶就可以知道當時正在發生的事情。這是個問題,'@ stage'不是固定的,它每改變一次'show'請求都會改變它的值,那麼我怎樣才能用更新後的'@ stage'無刷新更新視圖呢? – YoloSnake

+0

AJAX請求完全在後臺運行,默認情況下它們不會更新當前顯示的頁面。如果你的'show'動作返回HTML,你將不得不使用JavaScript自己解析出響應的新狀態,並手動更新當前頁面上的標籤。 –

+0

我唯一的想法是在setInterval函數中觸發一個Ajax請求,刷新'@ stage'。不知道如何實現它。 – YoloSnake